Skip to content

[Sema] Don't drop weak_import from a declaration that follows a declaration directly contained in a linkage-specification #85886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -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">;
"%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>;
Expand Down
20 changes: 11 additions & 9 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4611,16 +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>() &&
Old->getStorageClass() == SC_None &&
!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>())
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_definition);
// Remove weak_import attribute on new declaration.
New->dropAttr<WeakImportAttr>();
break;
}
}

if (const auto *ILA = New->getAttr<InternalLinkageAttr>())
if (!Old->hasAttr<InternalLinkageAttr>()) {
Expand Down
8 changes: 6 additions & 2 deletions clang/test/Sema/attr-weak.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ 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}}
extern int C __attribute__((weak_import)); // expected-warning {{an already-declared variable is made a weak_import declaration}}
int C; // expected-note {{previous definition is here}}
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 {{'C2' cannot be declared 'weak_import'}}

static int pr14946_x;
extern int pr14946_x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
Expand Down
7 changes: 7 additions & 0 deletions clang/test/SemaCXX/attr-weak.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Loading