This upgrades the warning when defining dllimport variables to an error
(consistent with GCC and MSVC).

-Nico
>From 8dae97f70a3def16774f58a64a8d0fe2308be31b Mon Sep 17 00:00:00 2001
From: Nico Rieck <[email protected]>
Date: Sat, 22 Feb 2014 21:01:23 +0100
Subject: [PATCH] Definition of dllimport globals is not allowed

Upgrades the warning to an error and clarifies the message by treating the
definition as error instead of the attribute.
---
 include/clang/Basic/DiagnosticSemaKinds.td |  2 ++
 lib/Sema/SemaDecl.cpp                      |  9 +++++++++
 lib/Sema/SemaDeclAttr.cpp                  |  9 ---------
 test/Sema/dllexport.c                      |  6 +++---
 test/Sema/dllimport.c                      | 14 +++++++++-----
 test/SemaCXX/dllexport.cpp                 |  6 +++---
 test/SemaCXX/dllimport.cpp                 | 14 +++++++++-----
 7 files changed, 35 insertions(+), 25 deletions(-)

diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index aaebf59..299d0c2 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2040,6 +2040,8 @@ def err_attribute_selectany_non_extern_data : Error<
 def warn_attribute_invalid_on_definition : Warning<
   "'%0' attribute cannot be specified on a definition">,
   InGroup<IgnoredAttributes>;
+def err_attribute_dllimport_data_definition : Error<
+  "definition of dllimport data">;
 def err_attribute_weakref_not_static : Error<
   "weakref declaration must have internal linkage">;
 def err_attribute_weakref_not_global_context : Error<
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 8e18710..4ea1ceb 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -8132,6 +8132,15 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
       return;
   }
 
+  // dllimport cannot be used on variable definitions.
+  if (const DLLImportAttr *ImportAttr = VDecl->getAttr<DLLImportAttr>()) {
+    if (!VDecl->isStaticDataMember()) {
+      Diag(VDecl->getLocation(), diag::err_attribute_dllimport_data_definition);
+      VDecl->setInvalidDecl();
+      return;
+    }
+  }
+
   if (VDecl->isLocalVarDecl() && VDecl->hasExternalStorage()) {
     // C99 6.7.8p5. C++ has no such restriction, but that is a defect.
     Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 7679fdb..6963584 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -3793,15 +3793,6 @@ DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range,
   if (D->hasAttr<DLLImportAttr>())
     return NULL;
 
-  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
-    if (VD->hasDefinition()) {
-      // dllimport cannot be applied to definitions.
-      Diag(D->getLocation(), diag::warn_attribute_invalid_on_definition)
-        << "dllimport";
-      return NULL;
-    }
-  }
-
   return ::new (Context) DLLImportAttr(Range, Context, AttrSpellingListIndex);
 }
 
diff --git a/test/Sema/dllexport.c b/test/Sema/dllexport.c
index fb209e1..eb39fbe 100644
--- a/test/Sema/dllexport.c
+++ b/test/Sema/dllexport.c
@@ -85,8 +85,8 @@ __declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B;
 __attribute__((dllimport, dllexport))       int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
 __declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
 
-__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
-__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
 
 __declspec(dllexport) extern int PrecedenceExternGlobalRedecl1;
 __declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
@@ -95,7 +95,7 @@ __declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warn
 __declspec(dllexport) extern int PrecedenceExternGlobalRedecl2;
 
 __declspec(dllexport) extern int PrecedenceGlobalRedecl1;
-__declspec(dllimport)        int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+__declspec(dllimport)        int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
 
 __declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
 __declspec(dllexport)        int PrecedenceGlobalRedecl2;
diff --git a/test/Sema/dllimport.c b/test/Sema/dllimport.c
index ee1ad88..615f8f7 100644
--- a/test/Sema/dllimport.c
+++ b/test/Sema/dllimport.c
@@ -20,16 +20,17 @@ struct __declspec(dllimport) Record {}; // expected-warning{{'dllimport' attribu
 // Import declaration.
 __declspec(dllimport) extern int ExternGlobalDecl;
 
-// dllimport implies a declaration. FIXME: This should not warn.
-__declspec(dllimport) int GlobalDecl; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+// dllimport implies a declaration.
+__declspec(dllimport) int GlobalDecl;
 
 // Not allowed on definitions.
-__declspec(dllimport) int GlobalInit1 = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
-int __declspec(dllimport) GlobalInit2 = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+__declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}}
+__declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}}
+int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}}
 
 // Declare, then reject definition.
 __declspec(dllimport) extern int ExternGlobalDeclInit;
-int ExternGlobalDeclInit = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+int ExternGlobalDeclInit = 1; // expected-error{{definition of dllimport data}}
 
 // Redeclarations
 __declspec(dllimport) extern int GlobalRedecl1;
@@ -37,7 +38,10 @@ __declspec(dllimport) extern int GlobalRedecl1;
 
 // Import in local scope.
 void functionScope() {
+  __declspec(dllimport)        int LocalVarDecl;
+  __declspec(dllimport)        int LocalVarDef = 1; // expected-error{{definition of dllimport data}}
   __declspec(dllimport) extern int ExternLocalVarDecl;
+  __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}}
 }
 
 
diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp
index 114ebd0..6476383 100644
--- a/test/SemaCXX/dllexport.cpp
+++ b/test/SemaCXX/dllexport.cpp
@@ -161,8 +161,8 @@ __declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B;
 __attribute__((dllimport, dllexport))       int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
 __declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
 
-__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
-__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
 
 __declspec(dllexport) extern int PrecedenceExternGlobalRedecl1;
 __declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
@@ -171,7 +171,7 @@ __declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warn
 __declspec(dllexport) extern int PrecedenceExternGlobalRedecl2;
 
 __declspec(dllexport) extern int PrecedenceGlobalRedecl1;
-__declspec(dllimport)        int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+__declspec(dllimport)        int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
 
 __declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
 __declspec(dllexport)        int PrecedenceGlobalRedecl2;
diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp
index d04a4b9..4a3ee20 100644
--- a/test/SemaCXX/dllimport.cpp
+++ b/test/SemaCXX/dllimport.cpp
@@ -32,16 +32,17 @@ enum __declspec(dllimport) Enum {}; // expected-warning{{'dllimport' attribute o
 // Import declaration.
 __declspec(dllimport) extern int ExternGlobalDecl;
 
-// dllimport implies a declaration. FIXME: This should not warn.
-__declspec(dllimport) int GlobalDecl; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+// dllimport implies a declaration.
+__declspec(dllimport) int GlobalDecl;
 
 // Not allowed on definitions.
-__declspec(dllimport) int GlobalInit1 = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
-int __declspec(dllimport) GlobalInit2 = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+__declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}}
+__declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}}
+int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}}
 
 // Declare, then reject definition.
 __declspec(dllimport) extern int ExternGlobalDeclInit;
-int ExternGlobalDeclInit = 1; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
+int ExternGlobalDeclInit = 1; // expected-error{{definition of dllimport data}}
 
 // Redeclarations
 __declspec(dllimport) extern int GlobalRedecl1;
@@ -49,7 +50,10 @@ __declspec(dllimport) extern int GlobalRedecl1;
 
 // Import in local scope.
 void functionScope() {
+  __declspec(dllimport)        int LocalVarDecl;
+  __declspec(dllimport)        int LocalVarDef = 1; // expected-error{{definition of dllimport data}}
   __declspec(dllimport) extern int ExternLocalVarDecl;
+  __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}}
 }
 
 
-- 
1.9.0.msysgit.0

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to