Skip to content

Commit 029eae4

Browse files
ahatanakyuxuanchen1997
authored andcommitted
[Sema] Don't drop weak_import from a declaration if its definition isn't seen (#85886)
I believe this is what the original commit (33e0226) was trying to do. This fixes a bug where clang removes the attribute from a declaration that follows a declaration directly contained in a linkage-specification. rdar://61865848
1 parent 94fc904 commit 029eae4

File tree

4 files changed

+25
-12
lines changed

4 files changed

+25
-12
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6075,7 +6075,7 @@ def note_extern_c_global_conflict : Note<
60756075
def note_extern_c_begins_here : Note<
60766076
"extern \"C\" language linkage specification begins here">;
60776077
def warn_weak_import : Warning <
6078-
"an already-declared variable is made a weak_import declaration %0">;
6078+
"%0 cannot be declared 'weak_import' because its definition has been provided">;
60796079
def ext_static_non_static : Extension<
60806080
"redeclaring non-static %0 as static is a Microsoft extension">,
60816081
InGroup<MicrosoftRedeclareStatic>;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4518,16 +4518,18 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
45184518
}
45194519

45204520
mergeDeclAttributes(New, Old);
4521-
// Warn if an already-declared variable is made a weak_import in a subsequent
4521+
// Warn if an already-defined variable is made a weak_import in a subsequent
45224522
// declaration
4523-
if (New->hasAttr<WeakImportAttr>() &&
4524-
Old->getStorageClass() == SC_None &&
4525-
!Old->hasAttr<WeakImportAttr>()) {
4526-
Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
4527-
Diag(Old->getLocation(), diag::note_previous_declaration);
4528-
// Remove weak_import attribute on new declaration.
4529-
New->dropAttr<WeakImportAttr>();
4530-
}
4523+
if (New->hasAttr<WeakImportAttr>())
4524+
for (auto *D = Old; D; D = D->getPreviousDecl()) {
4525+
if (D->isThisDeclarationADefinition() != VarDecl::DeclarationOnly) {
4526+
Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
4527+
Diag(D->getLocation(), diag::note_previous_definition);
4528+
// Remove weak_import attribute on new declaration.
4529+
New->dropAttr<WeakImportAttr>();
4530+
break;
4531+
}
4532+
}
45314533

45324534
if (const auto *ILA = New->getAttr<InternalLinkageAttr>())
45334535
if (!Old->hasAttr<InternalLinkageAttr>()) {

clang/test/Sema/attr-weak.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ struct __attribute__((weak_import)) s1 {}; // expected-warning {{'weak_import' a
1616
static int f(void) __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
1717
static int x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
1818

19-
int C; // expected-note {{previous declaration is here}}
20-
extern int C __attribute__((weak_import)); // expected-warning {{an already-declared variable is made a weak_import declaration}}
19+
int C; // expected-note {{previous definition is here}}
20+
extern int C __attribute__((weak_import)); // expected-warning {{'C' cannot be declared 'weak_import'}}
21+
22+
int C2; // expected-note {{previous definition is here}}
23+
extern int C2;
24+
extern int C2 __attribute__((weak_import)); // expected-warning {{'C2' cannot be declared 'weak_import'}}
2125

2226
static int pr14946_x;
2327
extern int pr14946_x __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}

clang/test/SemaCXX/attr-weak.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,10 @@ constexpr bool weak_method_is_non_null = &WithWeakMember::weak_method != nullptr
5656
// virtual member function is present.
5757
constexpr bool virtual_weak_method_is_non_null = &WithWeakMember::virtual_weak_method != nullptr; // expected-error {{must be initialized by a constant expression}}
5858
// expected-note@-1 {{comparison against pointer to weak member 'WithWeakMember::virtual_weak_method' can only be performed at runtime}}
59+
60+
// Check that no warnings are emitted.
61+
extern "C" int g0;
62+
extern int g0 __attribute__((weak_import));
63+
64+
extern "C" int g1 = 0; // expected-note {{previous definition is here}}
65+
extern int g1 __attribute__((weak_import)); // expected-warning {{attribute declaration must precede definition}}

0 commit comments

Comments
 (0)