summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp5
-rw-r--r--clang/test/CodeGen/dllimport.c8
-rw-r--r--clang/test/Sema/dllimport.c4
3 files changed, 15 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4abbbebf808..d24cf6a7bef 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/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<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;
diff --git a/clang/test/CodeGen/dllimport.c b/clang/test/CodeGen/dllimport.c
index 32ee81f8592..6ed60ea1e25 100644
--- a/clang/test/CodeGen/dllimport.c
+++ b/clang/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/clang/test/Sema/dllimport.c b/clang/test/Sema/dllimport.c
index 2702453b61c..30ea4f3089c 100644
--- a/clang/test/Sema/dllimport.c
+++ b/clang/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;
}
OpenPOWER on IntegriCloud