https://github.com/ahatanak updated https://github.com/llvm/llvm-project/pull/85886
>From d39667c7e65c10babb478d8f8d54fecb66d90568 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka <ahata...@gmail.com> Date: Tue, 19 Mar 2024 15:50:00 -0700 Subject: [PATCH 1/5] [Sema] Don't drop weak_import from a declaration that follows a declaration directly contained in a linkage-specification Only drop it if the declaration follows a definition. I believe this is what 33e022650adee965c65f9aea086ee74f3fd1bad5 was trying to do. rdar://61865848 --- clang/lib/Sema/SemaDecl.cpp | 3 +-- clang/test/SemaCXX/attr-weak.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 5850cd0ab6b9a..2e45f1191273a 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4613,8 +4613,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { mergeDeclAttributes(New, Old); // Warn if an already-declared variable is made a weak_import in a subsequent // declaration - if (New->hasAttr<WeakImportAttr>() && - Old->getStorageClass() == SC_None && + if (New->hasAttr<WeakImportAttr>() && Old->isThisDeclarationADefinition() && !Old->hasAttr<WeakImportAttr>()) { Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_declaration); diff --git a/clang/test/SemaCXX/attr-weak.cpp b/clang/test/SemaCXX/attr-weak.cpp index f065bfd9483f8..a2c5fd4abd35f 100644 --- a/clang/test/SemaCXX/attr-weak.cpp +++ b/clang/test/SemaCXX/attr-weak.cpp @@ -55,3 +55,10 @@ constexpr bool weak_method_is_non_null = &WithWeakMember::weak_method != nullptr // virtual member function is present. constexpr bool virtual_weak_method_is_non_null = &WithWeakMember::virtual_weak_method != nullptr; // expected-error {{must be initialized by a constant expression}} // expected-note@-1 {{comparison against pointer to weak member 'WithWeakMember::virtual_weak_method' can only be performed at runtime}} + +// Check that no warnings are emitted. +extern "C" int g0; +extern int g0 __attribute__((weak_import)); + +extern "C" int g1 = 0; // expected-note {{previous definition is here}} +extern int g1 __attribute__((weak_import)); // expected-warning {{attribute declaration must precede definition}} >From 33e3219c721d0c03f445c9bb977cb9f3809e74ac Mon Sep 17 00:00:00 2001 From: Akira Hatanaka <ahata...@gmail.com> Date: Wed, 8 May 2024 20:40:58 -0700 Subject: [PATCH 2/5] Check whether there's a definition at all --- clang/lib/Sema/SemaDecl.cpp | 23 +++++++++++++++++------ clang/test/Sema/attr-weak.c | 4 ++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 2e45f1191273a..0be6906026a85 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4613,12 +4613,23 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { mergeDeclAttributes(New, Old); // Warn if an already-declared variable is made a weak_import in a subsequent // declaration - if (New->hasAttr<WeakImportAttr>() && Old->isThisDeclarationADefinition() && - !Old->hasAttr<WeakImportAttr>()) { - Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName(); - Diag(Old->getLocation(), diag::note_previous_declaration); - // Remove weak_import attribute on new declaration. - New->dropAttr<WeakImportAttr>(); + if (New->hasAttr<WeakImportAttr>()) { + // We know there's no full definition as the attribute on New would have + // been removed otherwise. Just look for the most recent tentative + // definition. + VarDecl *TentativeDef = nullptr; + for (auto *D = Old; D; D = D->getPreviousDecl()) + if (D->isThisDeclarationADefinition() == VarDecl::TentativeDefinition) { + TentativeDef = D; + break; + } + + if (TentativeDef) { + Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName(); + Diag(TentativeDef->getLocation(), diag::note_previous_declaration); + // Remove weak_import attribute on new declaration. + New->dropAttr<WeakImportAttr>(); + } } if (const auto *ILA = New->getAttr<InternalLinkageAttr>()) diff --git a/clang/test/Sema/attr-weak.c b/clang/test/Sema/attr-weak.c index b827d1539b997..94e1723e125b6 100644 --- a/clang/test/Sema/attr-weak.c +++ b/clang/test/Sema/attr-weak.c @@ -19,6 +19,10 @@ static int x __attribute__((weak)); // expected-error {{weak declaration cannot 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}} +int C2; // expected-note {{previous declaration is here}} +extern int C2; +extern int C2 __attribute__((weak_import)); // expected-warning {{an already-declared variable is made a weak_import declaration}} + static int pr14946_x; extern int pr14946_x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} >From c33375cbc8863be911f7832538228cfde0e1d58d Mon Sep 17 00:00:00 2001 From: Akira Hatanaka <ahata...@gmail.com> Date: Thu, 9 May 2024 07:44:54 -0700 Subject: [PATCH 3/5] Improve the diagnostic message and check that the decl isn't DeclarationOnly --- .../clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Sema/SemaDecl.cpp | 24 +++++++------------ clang/test/Sema/attr-weak.c | 4 ++-- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8e97902564af0..687b1678f6923 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6018,7 +6018,7 @@ def note_extern_c_global_conflict : Note< def note_extern_c_begins_here : Note< "extern \"C\" language linkage specification begins here">; def warn_weak_import : Warning < - "an already-declared variable is made a weak_import declaration %0">; + "an already-defined variable is made a weak_import declaration %0">; def ext_static_non_static : Extension< "redeclaring non-static %0 as static is a Microsoft extension">, InGroup<MicrosoftRedeclareStatic>; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0be6906026a85..84cc8c6b64443 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4611,26 +4611,18 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { } mergeDeclAttributes(New, Old); - // Warn if an already-declared variable is made a weak_import in a subsequent + // Warn if an already-defined variable is made a weak_import in a subsequent // declaration - if (New->hasAttr<WeakImportAttr>()) { - // We know there's no full definition as the attribute on New would have - // been removed otherwise. Just look for the most recent tentative - // definition. - VarDecl *TentativeDef = nullptr; - for (auto *D = Old; D; D = D->getPreviousDecl()) - if (D->isThisDeclarationADefinition() == VarDecl::TentativeDefinition) { - TentativeDef = D; + if (New->hasAttr<WeakImportAttr>()) + for (auto *D = Old; D; D = D->getPreviousDecl()) { + if (D->isThisDeclarationADefinition() != VarDecl::DeclarationOnly) { + Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName(); + Diag(D->getLocation(), diag::note_previous_declaration); + // Remove weak_import attribute on new declaration. + New->dropAttr<WeakImportAttr>(); break; } - - if (TentativeDef) { - Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName(); - Diag(TentativeDef->getLocation(), diag::note_previous_declaration); - // Remove weak_import attribute on new declaration. - New->dropAttr<WeakImportAttr>(); } - } if (const auto *ILA = New->getAttr<InternalLinkageAttr>()) if (!Old->hasAttr<InternalLinkageAttr>()) { diff --git a/clang/test/Sema/attr-weak.c b/clang/test/Sema/attr-weak.c index 94e1723e125b6..3dbf46e65d05b 100644 --- a/clang/test/Sema/attr-weak.c +++ b/clang/test/Sema/attr-weak.c @@ -17,11 +17,11 @@ static int f(void) __attribute__((weak)); // expected-error {{weak declaration c static int x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} 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}} +extern int C __attribute__((weak_import)); // expected-warning {{an already-defined variable is made a weak_import declaration}} int C2; // expected-note {{previous declaration is here}} extern int C2; -extern int C2 __attribute__((weak_import)); // expected-warning {{an already-declared variable is made a weak_import declaration}} +extern int C2 __attribute__((weak_import)); // expected-warning {{an already-defined variable is made a weak_import declaration}} static int pr14946_x; extern int pr14946_x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} >From 0f18a7a7007967c231221b8eeacde265e1d0302d Mon Sep 17 00:00:00 2001 From: Akira Hatanaka <ahata...@gmail.com> Date: Thu, 9 May 2024 09:31:34 -0700 Subject: [PATCH 4/5] Fix note message --- clang/lib/Sema/SemaDecl.cpp | 2 +- clang/test/Sema/attr-weak.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 84cc8c6b64443..e2b143d0faca1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4617,7 +4617,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { for (auto *D = Old; D; D = D->getPreviousDecl()) { if (D->isThisDeclarationADefinition() != VarDecl::DeclarationOnly) { Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName(); - Diag(D->getLocation(), diag::note_previous_declaration); + Diag(D->getLocation(), diag::note_previous_definition); // Remove weak_import attribute on new declaration. New->dropAttr<WeakImportAttr>(); break; diff --git a/clang/test/Sema/attr-weak.c b/clang/test/Sema/attr-weak.c index 3dbf46e65d05b..9e343760ea887 100644 --- a/clang/test/Sema/attr-weak.c +++ b/clang/test/Sema/attr-weak.c @@ -16,10 +16,10 @@ struct __attribute__((weak_import)) s1 {}; // expected-warning {{'weak_import' a static int f(void) __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} static int x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} -int C; // expected-note {{previous declaration is here}} +int C; // expected-note {{previous definition is here}} extern int C __attribute__((weak_import)); // expected-warning {{an already-defined variable is made a weak_import declaration}} -int C2; // expected-note {{previous declaration is here}} +int C2; // expected-note {{previous definition is here}} extern int C2; extern int C2 __attribute__((weak_import)); // expected-warning {{an already-defined variable is made a weak_import declaration}} >From 0fcd6d80aee34ce0eaacc3c2c6712d42e587d232 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka <ahata...@gmail.com> Date: Wed, 17 Jul 2024 14:54:11 -0700 Subject: [PATCH 5/5] Improve diagnostic wording --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/test/Sema/attr-weak.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 687b1678f6923..40cea8bf29990 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6018,7 +6018,7 @@ def note_extern_c_global_conflict : Note< def note_extern_c_begins_here : Note< "extern \"C\" language linkage specification begins here">; def warn_weak_import : Warning < - "an already-defined variable is made a weak_import declaration %0">; + "%0 cannot be declared 'weak_import' because its definition has been provided">; def ext_static_non_static : Extension< "redeclaring non-static %0 as static is a Microsoft extension">, InGroup<MicrosoftRedeclareStatic>; diff --git a/clang/test/Sema/attr-weak.c b/clang/test/Sema/attr-weak.c index 9e343760ea887..f6482109bc9f6 100644 --- a/clang/test/Sema/attr-weak.c +++ b/clang/test/Sema/attr-weak.c @@ -17,11 +17,11 @@ static int f(void) __attribute__((weak)); // expected-error {{weak declaration c static int x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} int C; // expected-note {{previous definition is here}} -extern int C __attribute__((weak_import)); // expected-warning {{an already-defined variable is made a weak_import declaration}} +extern int C __attribute__((weak_import)); // expected-warning {{'C' cannot be declared 'weak_import'}} int C2; // expected-note {{previous definition is here}} extern int C2; -extern int C2 __attribute__((weak_import)); // expected-warning {{an already-defined variable is made a weak_import declaration}} +extern int C2 __attribute__((weak_import)); // expected-warning {{'C2' cannot be declared 'weak_import'}} static int pr14946_x; extern int pr14946_x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits