Don't suggest 'noreturn' for function template instantiations, because

it might be wrong for other instantiations of the same function
template. Fixes PR10801.

llvm-svn: 141559
This commit is contained in:
Douglas Gregor 2011-10-10 18:15:57 +00:00
parent 6ce53ae752
commit 0de5720737
2 changed files with 43 additions and 7 deletions

View 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

View 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);
}
}