From b567f63bf385a77f20f3118e9eb28734ba9f7cdd Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 31 Jul 2014 19:29:39 +0000 Subject: [PATCH] Local extern redeclarations of dllimport variables stay dllimport even if they don't specify the attribute git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@214425 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 5 +++-- test/CodeGen/dllimport.c | 8 ++++++++ test/Sema/dllimport.c | 4 ++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 4abbbebf80..d24cf6a7be 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5047,7 +5047,7 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl, } // A redeclaration is not allowed to drop a dllimport attribute, the only - // exception being inline function definitions. + // exceptions being inline function definitions and local extern declarations. // NB: MSVC converts such a declaration to dllexport. bool IsInline = false, IsStaticDataMember = false; if (const auto *VD = dyn_cast(NewDecl)) @@ -5057,7 +5057,8 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl, else if (const auto *FD = dyn_cast(NewDecl)) IsInline = FD->isInlined(); - if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember) { + if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember && + !NewDecl->isLocalExternDecl()) { S.Diag(NewDecl->getLocation(), diag::warn_redeclaration_without_attribute_prev_attribute_ignored) << NewDecl << OldImportAttr; diff --git a/test/CodeGen/dllimport.c b/test/CodeGen/dllimport.c index 32ee81f859..6ed60ea1e2 100644 --- a/test/CodeGen/dllimport.c +++ b/test/CodeGen/dllimport.c @@ -44,6 +44,14 @@ __declspec(dllimport) extern int GlobalRedecl3; extern int GlobalRedecl3; // dllimport ignored USEVAR(GlobalRedecl3) +// Redeclaration in local context. +// CHECK: @GlobalRedecl4 = external dllimport global i32 +__declspec(dllimport) int GlobalRedecl4; +int functionScope() { + extern int GlobalRedecl4; // still dllimport + return GlobalRedecl4; +} + //===----------------------------------------------------------------------===// diff --git a/test/Sema/dllimport.c b/test/Sema/dllimport.c index 2702453b61..30ea4f3089 100644 --- a/test/Sema/dllimport.c +++ b/test/Sema/dllimport.c @@ -74,6 +74,7 @@ __declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' __declspec(dllimport) float LocalRedecl1; // expected-note{{previous definition is here}} __declspec(dllimport) float LocalRedecl2; // expected-note{{previous definition is here}} __declspec(dllimport) float LocalRedecl3; // expected-note{{previous definition is here}} +__declspec(dllimport) float LocalRedecl4; void functionScope() { __declspec(dllimport) int LocalRedecl1; // expected-error{{redefinition of 'LocalRedecl1' with a different type: 'int' vs 'float'}} int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redefinition of 'LocalRedecl2' with a different type: 'int *' vs 'float'}} @@ -84,6 +85,9 @@ void functionScope() { __declspec(dllimport) extern int ExternLocalVarDecl; __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}} __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}} + + // Local extern redeclaration does not drop the attribute. + extern float LocalRedecl4; } -- 2.40.0