Эх сурвалжийг харах

Simple hack to do unreachable code analysis on template patterns.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148774 91177308-0d34-0410-b5e6-96231b3b80d8
David Blaikie 13 жил өмнө
parent
commit
36b7c63664

+ 4 - 5
lib/Sema/AnalysisBasedWarnings.cpp

@@ -782,8 +782,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
     return;
     return;
 
 
   // For code in dependent contexts, we'll do this at instantiation time.
   // For code in dependent contexts, we'll do this at instantiation time.
-  if (cast<DeclContext>(D)->isDependentContext())
-    return;
+  bool Dependent = cast<DeclContext>(D)->isDependentContext();
 
 
   if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) {
   if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) {
     // Flush out any possibly unreachable diagnostics.
     // Flush out any possibly unreachable diagnostics.
@@ -826,7 +825,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
   // Construct the analysis context with the specified CFG build options.
   // Construct the analysis context with the specified CFG build options.
   
   
   // Emit delayed diagnostics.
   // Emit delayed diagnostics.
-  if (!fscope->PossiblyUnreachableDiags.empty()) {
+  if (!fscope->PossiblyUnreachableDiags.empty() && !Dependent) {
     bool analyzed = false;
     bool analyzed = false;
 
 
     // Register the expressions with the CFGBuilder.
     // Register the expressions with the CFGBuilder.
@@ -874,7 +873,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
   
   
   
   
   // Warning: check missing 'return'
   // Warning: check missing 'return'
-  if (P.enableCheckFallThrough) {
+  if (P.enableCheckFallThrough && !Dependent) {
     const CheckFallThroughDiagnostics &CD =
     const CheckFallThroughDiagnostics &CD =
       (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
       (isa<BlockDecl>(D) ? CheckFallThroughDiagnostics::MakeForBlock()
                          : CheckFallThroughDiagnostics::MakeForFunction(D));
                          : CheckFallThroughDiagnostics::MakeForFunction(D));
@@ -895,7 +894,7 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
   }
   }
 
 
   // Check for thread safety violations
   // Check for thread safety violations
-  if (P.enableThreadSafetyAnalysis) {
+  if (P.enableThreadSafetyAnalysis && !Dependent) {
     SourceLocation FL = AC.getDecl()->getLocation();
     SourceLocation FL = AC.getDecl()->getLocation();
     thread_safety::ThreadSafetyReporter Reporter(S, FL);
     thread_safety::ThreadSafetyReporter Reporter(S, FL);
     thread_safety::runThreadSafetyAnalysis(AC, Reporter);
     thread_safety::runThreadSafetyAnalysis(AC, Reporter);

+ 7 - 3
test/SemaCXX/array-bounds.cpp

@@ -73,17 +73,21 @@ void test() {
   (*array_ptr)[3] = 1; // expected-warning {{array index 3 is past the end of the array (which contains 2 elements)}}
   (*array_ptr)[3] = 1; // expected-warning {{array index 3 is past the end of the array (which contains 2 elements)}}
 }
 }
 
 
+// FIXME: we should see the next note only 3 times and the following warning once, not twice
+//        since it is independent of the template parameter 'I'.
 template <int I> struct S {
 template <int I> struct S {
-  char arr[I]; // expected-note 2 {{declared here}}
+  char arr[I]; // expected-note 4 {{declared here}}
 };
 };
 template <int I> void f() {
 template <int I> void f() {
   S<3> s;
   S<3> s;
-  s.arr[4] = 0; // expected-warning {{array index 4 is past the end of the array (which contains 3 elements)}}
-  s.arr[I] = 0; // expected-warning {{array index 5 is past the end of the array (which contains 3 elements)}}
+  s.arr[4] = 0; // expected-warning 2 {{array index 4 is past the end of the array (which contains 3 elements)}}
+  s.arr[I] = 0; // expected-warning {{array index 5 is past the end of the array (which contains 3 elements)}} \
+                   expected-warning {{array index 3 is past the end of the array (which contains 3 elements)}}
 }
 }
 
 
 void test_templates() {
 void test_templates() {
   f<5>(); // expected-note {{in instantiation}}
   f<5>(); // expected-note {{in instantiation}}
+  f<3>(); // expected-note {{in instantiation}}
 }
 }
 
 
 #define SIZE 10
 #define SIZE 10

+ 18 - 1
test/SemaCXX/warn-unreachable.cpp

@@ -98,6 +98,24 @@ void test_unreachable_templates_harness() {
   test_unreachable_templates<TestUnreachableB>(); 
   test_unreachable_templates<TestUnreachableB>(); 
 }
 }
 
 
+// Do warn about non-dependent unreachable code in templates
+// Warn even if the template is never instantiated
+
+template<typename T> void test_non_dependent_unreachable_templates() {
+  TestUnreachableA::foo();
+  isUnreachable(); // expected-warning {{will never be executed}}
+}
+
+// Warn only once even if the template is instantiated multiple times
+
+template<typename T> void test_non_dependent_unreachable_templates2() {
+  TestUnreachableA::foo();
+  isUnreachable(); // expected-warning {{will never be executed}}
+}
+
+template void test_non_dependent_unreachable_templates2<int>();
+template void test_non_dependent_unreachable_templates2<long>();
+
 // Do warn about explict template specializations, as they represent
 // Do warn about explict template specializations, as they represent
 // actual concrete functions that somebody wrote.
 // actual concrete functions that somebody wrote.
 
 
@@ -106,4 +124,3 @@ template <> void funcToSpecialize<int>() {
   halt();
   halt();
   dead(); // expected-warning {{will never be executed}}
   dead(); // expected-warning {{will never be executed}}
 }
 }
-