]> granicus.if.org Git - clang/commitdiff
Don't suggest 'noreturn' for function template instantiations, because
authorDouglas Gregor <dgregor@apple.com>
Mon, 10 Oct 2011 18:15:57 +0000 (18:15 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 10 Oct 2011 18:15:57 +0000 (18:15 +0000)
it might be wrong for other instantiations of the same function
template. Fixes PR10801.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141559 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/AnalysisBasedWarnings.cpp
test/SemaCXX/warn-missing-noreturn.cpp

index e42370d1a39cf6e5ec6881c9d44f17f1c459ec92..f461772ba7d4fe6a3be11440dea2cd56086d7033 100644 (file)
@@ -239,7 +239,23 @@ struct CheckFallThroughDiagnostics {
     if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Func))
       isVirtualMethod = Method->isVirtual();
     
-    if (!isVirtualMethod)
+    // 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 (!isVirtualMethod && !isTemplateInstantiation)
       D.diag_NeverFallThroughOrReturn =
         diag::warn_suggest_noreturn_function;
     else
index ac568a5d81c90d1d0fe7fb2b8834f70e3494a518..8072ac6b8249a5b2f6bc7cfcc90c7b25303828d9 100644 (file)
@@ -1,27 +1,27 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -Wmissing-noreturn -Wreturn-type
 void f() __attribute__((noreturn));
 
-template<typename T> void g(T) { // expected-warning {{function 'g<int>' could be declared with attribute 'noreturn'}}
+template<typename T> void g(T) {
   f();
 }
 
-template void g<int>(int); // expected-note {{in instantiation of function template specialization 'g<int>' requested here}}
+template void g<int>(int);
 
 template<typename T> struct A {
-  void g() { // expected-warning {{function 'g' could be declared with attribute 'noreturn'}}
+  void g() {
     f();
   }
 };
 
-template struct A<int>; // expected-note {{in instantiation of member function 'A<int>::g' requested here}}
+template struct A<int>;
 
 struct B {
-  template<typename T> void g(T) { // expected-warning {{function 'g<int>' could be declared with attribute 'noreturn'}}
+  template<typename T> void g(T) {
     f();
   }
 };
 
-template void B::g<int>(int); // expected-note {{in instantiation of function template specialization 'B::g<int>' requested here}}
+template void B::g<int>(int);
 
 // We don't want a warning here.
 struct X {
@@ -103,3 +103,23 @@ rdar8875247_B test_rdar8875247_B() {
   return f;
 } // no-warning
 
+namespace PR10801 {
+  struct Foo {
+    void wibble() __attribute((__noreturn__));
+  };
+
+  struct Bar {
+    void wibble();
+  };
+
+  template <typename T> void thingy(T thing) {
+    thing.wibble();
+  }
+
+  void test() {
+    Foo f;
+    Bar b;
+    thingy(f);
+    thingy(b);
+  }
+}