Skip to content

Commit f6ee937

Browse files
ahatanakahatanaka
authored andcommitted
[Sema] Don't drop weak_import from a declaration if its definition isn't seen (llvm#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 (cherry picked from commit 884772f) Conflicts: clang/test/Sema/attr-weak.c
1 parent 4ee0677 commit f6ee937

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
@@ -5925,7 +5925,7 @@ def note_extern_c_global_conflict : Note<
59255925
def note_extern_c_begins_here : Note<
59265926
"extern \"C\" language linkage specification begins here">;
59275927
def warn_weak_import : Warning <
5928-
"an already-declared variable is made a weak_import declaration %0">;
5928+
"%0 cannot be declared 'weak_import' because its definition has been provided">;
59295929
def ext_static_non_static : Extension<
59305930
"redeclaring non-static %0 as static is a Microsoft extension">,
59315931
InGroup<MicrosoftRedeclareStatic>;

clang/lib/Sema/SemaDecl.cpp

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

45894589
mergeDeclAttributes(New, Old);
4590-
// Warn if an already-declared variable is made a weak_import in a subsequent
4590+
// Warn if an already-defined variable is made a weak_import in a subsequent
45914591
// declaration
4592-
if (New->hasAttr<WeakImportAttr>() &&
4593-
Old->getStorageClass() == SC_None &&
4594-
!Old->hasAttr<WeakImportAttr>()) {
4595-
Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
4596-
Diag(Old->getLocation(), diag::note_previous_declaration);
4597-
// Remove weak_import attribute on new declaration.
4598-
New->dropAttr<WeakImportAttr>();
4599-
}
4592+
if (New->hasAttr<WeakImportAttr>())
4593+
for (auto *D = Old; D; D = D->getPreviousDecl()) {
4594+
if (D->isThisDeclarationADefinition() != VarDecl::DeclarationOnly) {
4595+
Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
4596+
Diag(D->getLocation(), diag::note_previous_definition);
4597+
// Remove weak_import attribute on new declaration.
4598+
New->dropAttr<WeakImportAttr>();
4599+
break;
4600+
}
4601+
}
46004602

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

clang/test/Sema/attr-weak.c

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

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

2327
static int pr14946_x;
2428
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
@@ -55,3 +55,10 @@ constexpr bool weak_method_is_non_null = &WithWeakMember::weak_method != nullptr
5555
// virtual member function is present.
5656
constexpr bool virtual_weak_method_is_non_null = &WithWeakMember::virtual_weak_method != nullptr; // expected-error {{must be initialized by a constant expression}}
5757
// expected-note@-1 {{comparison against pointer to weak member 'WithWeakMember::virtual_weak_method' can only be performed at runtime}}
58+
59+
// Check that no warnings are emitted.
60+
extern "C" int g0;
61+
extern int g0 __attribute__((weak_import));
62+
63+
extern "C" int g1 = 0; // expected-note {{previous definition is here}}
64+
extern int g1 __attribute__((weak_import)); // expected-warning {{attribute declaration must precede definition}}

0 commit comments

Comments
 (0)