[cfe-commits] r145547 - in /cfe/trunk: include/clang/AST/Decl.h lib/AST/Decl.cpp lib/Sema/AnalysisBasedWarnings.cpp lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp test/SemaCXX/warn-unreachable.cpp

Ted Kremenek kremenek at apple.com
Wed Nov 30 16:59:18 PST 2011


Author: kremenek
Date: Wed Nov 30 18:59:17 2011
New Revision: 145547

URL: http://llvm.org/viewvc/llvm-project?rev=145547&view=rev
Log:
Further tweak -Wurneachable-code and templates by allowing the warning to run on
explicit template specializations (which represent actual functions somebody wrote).

Along the way, refactor some other code which similarly cares about whether or
not they are looking at a template instantiation.

Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
    cfe/trunk/test/SemaCXX/warn-unreachable.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=145547&r1=145546&r2=145547&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Nov 30 18:59:17 2011
@@ -1909,6 +1909,10 @@
   /// be implicitly instantiated.
   bool isImplicitlyInstantiable() const;
 
+  /// \brief Determines if the given function was instantiated from a
+  /// function template.
+  bool isTemplateInstantiation() const;
+
   /// \brief Retrieve the function declaration from which this function could
   /// be instantiated, if it is an instantiation (rather than a non-template
   /// or a specialization, for example).

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=145547&r1=145546&r2=145547&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed Nov 30 18:59:17 2011
@@ -1951,7 +1951,20 @@
     return true;
 
   return PatternDecl->isInlined();
-}                      
+}
+
+bool FunctionDecl::isTemplateInstantiation() const {
+  switch (getTemplateSpecializationKind()) {
+    case TSK_Undeclared:
+    case TSK_ExplicitSpecialization:
+      return false;      
+    case TSK_ImplicitInstantiation:
+    case TSK_ExplicitInstantiationDeclaration:
+    case TSK_ExplicitInstantiationDefinition:
+      return true;
+  }
+  llvm_unreachable("All TSK values handled.");
+}
    
 FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
   // Handle class scope explicit specialization special case.

Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=145547&r1=145546&r2=145547&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Wed Nov 30 18:59:17 2011
@@ -241,19 +241,8 @@
     
     // Don't suggest that template instantiations be marked "noreturn"
     bool isTemplateInstantiation = false;
-    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func)) {
-      switch (Function->getTemplateSpecializationKind()) {
-      case TSK_Undeclared:
-      case TSK_ExplicitSpecialization:
-        break;
-        
-      case TSK_ImplicitInstantiation:
-      case TSK_ExplicitInstantiationDeclaration:
-      case TSK_ExplicitInstantiationDefinition:
-        isTemplateInstantiation = true;
-        break;
-      }
-    }
+    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Func))
+      isTemplateInstantiation = Function->isTemplateInstantiation();
         
     if (!isVirtualMethod && !isTemplateInstantiation)
       D.diag_NeverFallThroughOrReturn =
@@ -919,7 +908,10 @@
     // Different template instantiations can effectively change the control-flow
     // and it is very difficult to prove that a snippet of code in a template
     // is unreachable for all instantiations.
-    if (S.ActiveTemplateInstantiations.empty())
+    bool isTemplateInstantiation = false;
+    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
+      isTemplateInstantiation = Function->isTemplateInstantiation();
+    if (!isTemplateInstantiation)
       CheckUnreachable(S, AC);
   }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp?rev=145547&r1=145546&r2=145547&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp Wed Nov 30 18:59:17 2011
@@ -54,10 +54,11 @@
                                               BugReporter &B,
                                               ExprEngine &Eng) const {
   CFGBlocksSet reachable, visited;
-
+  
   if (Eng.hasWorkRemaining())
     return;
 
+  const Decl *D = 0;
   CFG *C = 0;
   ParentMap *PM = 0;
   const LocationContext *LC = 0;
@@ -67,6 +68,8 @@
     const ProgramPoint &P = I->getLocation();
     LC = P.getLocationContext();
 
+    if (!D)
+      D = LC->getAnalysisDeclContext()->getDecl();
     // Save the CFG if we don't have it already
     if (!C)
       C = LC->getAnalysisDeclContext()->getUnoptimizedCFG();
@@ -80,8 +83,15 @@
   }
 
   // Bail out if we didn't get the CFG or the ParentMap.
-  if (!C || !PM)
+  if (!D || !C || !PM)
     return;
+  
+  // Don't do anything for template instantiations.  Proving that code
+  // in a template instantiation is unreachable means proving that it is
+  // unreachable in all instantiations.
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+    if (FD->isTemplateInstantiation())
+      return;
 
   // Find CFGBlocks that were not covered by any node
   for (CFG::const_iterator I = C->begin(), E = C->end(); I != E; ++I) {

Modified: cfe/trunk/test/SemaCXX/warn-unreachable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unreachable.cpp?rev=145547&r1=145546&r2=145547&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-unreachable.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-unreachable.cpp Wed Nov 30 18:59:17 2011
@@ -98,3 +98,12 @@
   test_unreachable_templates<TestUnreachableB>(); 
 }
 
+// Do warn about explict template specializations, as they represent
+// actual concrete functions that somebody wrote.
+
+template <typename T> void funcToSpecialize() {}
+template <> void funcToSpecialize<int>() {
+  halt();
+  dead(); // expected-warning {{will never be executed}}
+}
+





More information about the cfe-commits mailing list