From: Chandler Carruth Date: Wed, 31 Aug 2011 09:01:53 +0000 (+0000) Subject: Improve the diagnostic text for -Wmissing-noreturn to include the name X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b0656ec72e25e5c8e463c2dc39914636f0cb06d1;p=clang Improve the diagnostic text for -Wmissing-noreturn to include the name of the function in question when applicable (that is, not for blocks). Patch by Joerg Sonnenberger with some stylistic tweaks by me. When discussing this weth Joerg, streaming the decl directly into the diagnostic didn't work because we have a pointer-to-const, and the overload doesn't accept such. In order to make my style tweaks to the patch, I first changed the overload to accept a pointer-to-const, and then changed the diagnostic printing layer to also use a pointer-to-const, cleaning up a gross line of code along the way. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138854 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 487a7ae242..934f20ff43 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -3030,7 +3030,7 @@ public: /// Insertion operator for diagnostics. This allows sending NamedDecl's /// into a diagnostic with <<. inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, - NamedDecl* ND) { + const NamedDecl* ND) { DB.AddTaggedVal(reinterpret_cast(ND), Diagnostic::ak_nameddecl); return DB; } diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 224853c34b..89bc106450 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -236,10 +236,10 @@ def err_maybe_falloff_nonvoid_block : Error< def err_falloff_nonvoid_block : Error< "control reaches end of non-void block">; def warn_suggest_noreturn_function : Warning< - "function could be attribute 'noreturn'">, + "function %0 could be declared with attribute 'noreturn'">, InGroup>, DefaultIgnore; def warn_suggest_noreturn_block : Warning< - "block could be attribute 'noreturn'">, + "block could be declared with attribute 'noreturn'">, InGroup>, DefaultIgnore; def warn_unreachable : Warning<"will never be executed">, InGroup>, DefaultIgnore; diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp index c93bbe60ab..e6de54c907 100644 --- a/lib/AST/ASTDiagnostic.cpp +++ b/lib/AST/ASTDiagnostic.cpp @@ -269,8 +269,8 @@ void clang::FormatASTNodeDiagnosticArgument( "Invalid modifier for NamedDecl* argument"); Qualified = false; } - reinterpret_cast(Val)-> - getNameForDiagnostic(S, Context.PrintingPolicy, Qualified); + const NamedDecl *ND = reinterpret_cast(Val); + ND->getNameForDiagnostic(S, Context.PrintingPolicy, Qualified); break; } case Diagnostic::ak_nestednamespec: { diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index f3f168a5c1..b11089cc1b 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -376,9 +376,14 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, CD.diag_AlwaysFallThrough_ReturnsNonVoid); break; case NeverFallThroughOrReturn: - if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) - S.Diag(Compound->getLBracLoc(), - CD.diag_NeverFallThroughOrReturn); + if (ReturnsVoid && !HasNoReturn && CD.diag_NeverFallThroughOrReturn) { + if (const FunctionDecl *FD = dyn_cast(D)) { + S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn) + << FD; + } else { + S.Diag(Compound->getLBracLoc(), CD.diag_NeverFallThroughOrReturn); + } + } break; case NeverFallThrough: break; diff --git a/test/Sema/return-noreturn.c b/test/Sema/return-noreturn.c index ff43754a42..448fce77cd 100644 --- a/test/Sema/return-noreturn.c +++ b/test/Sema/return-noreturn.c @@ -1,8 +1,8 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks -Wmissing-noreturn -Wno-unreachable-code int j; -void test1() { // expected-warning {{function could be attribute 'noreturn'}} - ^ (void) { while (1) { } }(); // expected-warning {{block could be attribute 'noreturn'}} +void test1() { // expected-warning {{function 'test1' could be declared with attribute 'noreturn'}} + ^ (void) { while (1) { } }(); // expected-warning {{block could be declared with attribute 'noreturn'}} ^ (void) { if (j) while (1) { } }(); while (1) { } } diff --git a/test/SemaCXX/warn-missing-noreturn.cpp b/test/SemaCXX/warn-missing-noreturn.cpp index 4caff66af7..ac568a5d81 100644 --- a/test/SemaCXX/warn-missing-noreturn.cpp +++ b/test/SemaCXX/warn-missing-noreturn.cpp @@ -1,14 +1,14 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -Wmissing-noreturn -Wreturn-type void f() __attribute__((noreturn)); -template void g(T) { // expected-warning {{function could be attribute 'noreturn'}} +template void g(T) { // expected-warning {{function 'g' could be declared with attribute 'noreturn'}} f(); } template void g(int); // expected-note {{in instantiation of function template specialization 'g' requested here}} template struct A { - void g() { // expected-warning {{function could be attribute 'noreturn'}} + void g() { // expected-warning {{function 'g' could be declared with attribute 'noreturn'}} f(); } }; @@ -16,7 +16,7 @@ template struct A { template struct A; // expected-note {{in instantiation of member function 'A::g' requested here}} struct B { - template void g(T) { // expected-warning {{function could be attribute 'noreturn'}} + template void g(T) { // expected-warning {{function 'g' could be declared with attribute 'noreturn'}} f(); } }; @@ -61,7 +61,7 @@ namespace test2 { void *f; A() : f(0) { } - A(int) : f(h()) { } // expected-warning {{function could be attribute 'noreturn'}} + A(int) : f(h()) { } // expected-warning {{function 'A' could be declared with attribute 'noreturn'}} A(char) : f(j()) { } A(bool b) : f(b ? h() : j()) { } }; diff --git a/test/SemaObjC/return.m b/test/SemaObjC/return.m index 3a626e3696..88e6e6381e 100644 --- a/test/SemaObjC/return.m +++ b/test/SemaObjC/return.m @@ -14,7 +14,7 @@ void test2(int a) { } // PR5286 -void test3(int a) { // expected-warning {{function could be attribute 'noreturn'}} +void test3(int a) { // expected-warning {{function 'test3' could be declared with attribute 'noreturn'}} while (1) { if (a) @throw (id)0;