]> granicus.if.org Git - clang/commitdiff
Local extern redeclarations of dllimport variables stay dllimport even if they don...
authorHans Wennborg <hans@hanshq.net>
Thu, 31 Jul 2014 19:29:39 +0000 (19:29 +0000)
committerHans Wennborg <hans@hanshq.net>
Thu, 31 Jul 2014 19:29:39 +0000 (19:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@214425 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
test/CodeGen/dllimport.c
test/Sema/dllimport.c

index 4abbbebf8087d573afe849ce0137b1c8d7e74d50..d24cf6a7bef000e3a134d4364f45303cda34e9cb 100644 (file)
@@ -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<VarDecl>(NewDecl))
@@ -5057,7 +5057,8 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
   else if (const auto *FD = dyn_cast<FunctionDecl>(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;
index 32ee81f85924f176fb6fa773c7f990637c78407d..6ed60ea1e254f0a14f1dae6a9ad9d4bee3cb3018 100644 (file)
@@ -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;
+}
+
 
 
 //===----------------------------------------------------------------------===//
index 2702453b61c0849a81401cbcb01ace13c05b8e83..30ea4f3089c70138692ae8bfaa72015368433eed 100644 (file)
@@ -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;
 }