diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5571,8 +5571,8 @@ def err_undefined_inline_var : Error<"inline variable %q0 is not defined">; def note_used_here : Note<"used here">; -def err_internal_linkage_redeclaration : Error< - "'internal_linkage' attribute does not appear on the first declaration of %0">; +def err_attribute_missing_on_first_decl : Error< + "%0 attribute does not appear on the first declaration">; def warn_internal_linkage_local_storage : Warning< "'internal_linkage' attribute on a non-static local variable is ignored">, InGroup; @@ -9676,10 +9676,6 @@ InGroup; def err_noreturn_block_has_return_expr : Error< "block declared 'noreturn' should not return">; -def err_noreturn_missing_on_first_decl : Error< - "function declared '[[noreturn]]' after its first declaration">; -def note_noreturn_missing_first_decl : Note< - "declaration missing '[[noreturn]]' attribute is here">; def err_carries_dependency_missing_on_first_decl : Error< "%select{function|parameter}0 declared '[[carries_dependency]]' " "after its first declaration">; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3353,13 +3353,13 @@ } } - if (New->hasAttr() && - !Old->hasAttr()) { - Diag(New->getLocation(), diag::err_internal_linkage_redeclaration) - << New->getDeclName(); - notePreviousDefinition(Old, New->getLocation()); - New->dropAttr(); - } + if (const auto *ILA = New->getAttr()) + if (!Old->hasAttr()) { + Diag(New->getLocation(), diag::err_attribute_missing_on_first_decl) + << ILA; + notePreviousDefinition(Old, New->getLocation()); + New->dropAttr(); + } if (CheckRedeclarationModuleOwnership(New, Old)) return true; @@ -3678,12 +3678,12 @@ // The first declaration of a function shall specify the noreturn // attribute if any declaration of that function specifies the noreturn // attribute. - const CXX11NoReturnAttr *NRA = New->getAttr(); - if (NRA && !Old->hasAttr()) { - Diag(NRA->getLocation(), diag::err_noreturn_missing_on_first_decl); - Diag(Old->getFirstDecl()->getLocation(), - diag::note_noreturn_missing_first_decl); - } + if (const auto *NRA = New->getAttr()) + if (!Old->hasAttr()) { + Diag(NRA->getLocation(), diag::err_attribute_missing_on_first_decl) + << NRA; + notePreviousDefinition(Old, New->getLocation()); + } // C++11 [dcl.attr.depend]p2: // The first declaration of a function shall specify the @@ -4166,13 +4166,13 @@ New->dropAttr(); } - if (New->hasAttr() && - !Old->hasAttr()) { - Diag(New->getLocation(), diag::err_internal_linkage_redeclaration) - << New->getDeclName(); - notePreviousDefinition(Old, New->getLocation()); - New->dropAttr(); - } + if (const auto *ILA = New->getAttr()) + if (!Old->hasAttr()) { + Diag(New->getLocation(), diag::err_attribute_missing_on_first_decl) + << ILA; + notePreviousDefinition(Old, New->getLocation()); + New->dropAttr(); + } // Merge the types. VarDecl *MostRecent = Old->getMostRecentDecl(); diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp --- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp @@ -24,8 +24,8 @@ [[noreturn]] int e() { b2(); } // ok -int f(); // expected-note {{declaration missing '[[noreturn]]' attribute is here}} -[[noreturn]] int f(); // expected-error {{function declared '[[noreturn]]' after its first declaration}} +int f(); // expected-note {{previous definition is here}} +[[noreturn]] int f(); // expected-error {{'noreturn' attribute does not appear on the first declaration}} int f(); [[noreturn]] int g(); diff --git a/clang/test/Sema/internal_linkage.c b/clang/test/Sema/internal_linkage.c --- a/clang/test/Sema/internal_linkage.c +++ b/clang/test/Sema/internal_linkage.c @@ -8,7 +8,7 @@ int var4 __attribute__((common)); // expected-note{{previous definition is here}} expected-note{{conflicting attribute is here}} int var4 __attribute__((internal_linkage)); // expected-error{{'internal_linkage' and 'common' attributes are not compatible}} \ - // expected-error{{'internal_linkage' attribute does not appear on the first declaration of 'var4'}} + // expected-error{{'internal_linkage' attribute does not appear on the first declaration}} int var5 __attribute__((internal_linkage)); // expected-note{{conflicting attribute is here}} int var5 __attribute__((common)); // expected-error{{'common' and 'internal_linkage' attributes are not compatible}} diff --git a/clang/test/SemaCXX/internal_linkage.cpp b/clang/test/SemaCXX/internal_linkage.cpp --- a/clang/test/SemaCXX/internal_linkage.cpp +++ b/clang/test/SemaCXX/internal_linkage.cpp @@ -20,9 +20,9 @@ }; }; -__attribute__((internal_linkage)) void A::f4() {} // expected-error{{'internal_linkage' attribute does not appear on the first declaration of 'f4'}} +__attribute__((internal_linkage)) void A::f4() {} // expected-error{{'internal_linkage' attribute does not appear on the first declaration}} -__attribute__((internal_linkage)) int A::zz; // expected-error{{'internal_linkage' attribute does not appear on the first declaration of 'zz'}} +__attribute__((internal_linkage)) int A::zz; // expected-error{{'internal_linkage' attribute does not appear on the first declaration}} namespace Z __attribute__((internal_linkage)) { // expected-warning{{'internal_linkage' attribute only applies to}} }