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; + Diag(Old->getLocation(), diag::note_previous_declaration); + 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; + Diag(Old->getLocation(), diag::note_previous_declaration); + } // C++11 [dcl.attr.depend]p2: // The first declaration of a function shall specify the @@ -4161,18 +4161,18 @@ Old->getStorageClass() == SC_None && !Old->hasAttr()) { Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName(); - notePreviousDefinition(Old, New->getLocation()); + Diag(Old->getLocation(), diag::note_previous_declaration); // Remove weak_import attribute on new declaration. 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; + Diag(Old->getLocation(), diag::note_previous_declaration); + 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 declaration 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/attr-weak.c b/clang/test/Sema/attr-weak.c --- a/clang/test/Sema/attr-weak.c +++ b/clang/test/Sema/attr-weak.c @@ -17,7 +17,7 @@ static int x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} // rdar://9538608 -int C; // expected-note {{previous definition is here}} +int C; // expected-note {{previous declaration is here}} extern int C __attribute__((weak_import)); // expected-warning {{an already-declared variable is made a weak_import declaration}} static int pr14946_x; 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 @@ -6,9 +6,9 @@ int var3 __attribute__((common,internal_linkage)); // expected-error{{'internal_linkage' and 'common' attributes are not compatible}} \ // expected-note{{conflicting attribute is here}} -int var4 __attribute__((common)); // expected-note{{previous definition is here}} expected-note{{conflicting attribute is here}} +int var4 __attribute__((common)); // expected-note{{previous declaration 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 @@ -10,8 +10,8 @@ void f1() __attribute__((internal_linkage)); void f2() __attribute__((internal_linkage)) {} static void f3() __attribute__((internal_linkage)) {} - void f4(); // expected-note{{previous definition is here}} - static int zz; // expected-note{{previous definition is here}} + void f4(); // expected-note{{previous declaration is here}} + static int zz; // expected-note{{previous declaration is here}} A() __attribute__((internal_linkage)) {} ~A() __attribute__((internal_linkage)) {} A& operator=(const A&) __attribute__((internal_linkage)) { return *this; } @@ -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}} }