Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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">;
"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>;
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 {{an already-defined variable is made a weak_import declaration}}

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}}

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}}