[PATCH] Don't allow dllimport variables in constant initializers

Hans Wennborg hans at chromium.org
Wed Jun 25 15:13:47 PDT 2014


Hi majnemer, hansw,

This is a follow-up to David's r211677. For the following code, we would end up referring to 'foo' in the initializer for 'arr', and then fail to link, because 'foo' is dllimport and needs to be accessed through the __imp_?foo.

http://reviews.llvm.org/D4299

Files:
  lib/AST/ExprConstant.cpp
  lib/Sema/SemaTemplate.cpp
  test/CodeGenCXX/dllimport.cpp
  test/Parser/MicrosoftExtensions.cpp
  test/SemaCXX/PR19955.cpp

Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -1275,13 +1275,8 @@
       if (Var->getTLSKind())
         return false;
 
-      // Check if this is a dllimport variable.  Fail evaluation if we care
-      // about side effects; a dllimport variable rarely acts like a constant
-      // except in places like template arguments.  It never acts like a
-      // constant in C.
-      if ((!Info.getLangOpts().CPlusPlus ||
-           !Info.keepEvaluatingAfterSideEffect()) &&
-          Var->hasAttr<DLLImportAttr>())
+      // A dllimport variable never acts like a constant.
+      if (Var->hasAttr<DLLImportAttr>())
         return false;
     }
     if (const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
@@ -1295,9 +1290,7 @@
       // The C language has no notion of ODR; furthermore, it has no notion of
       // dynamic initialization.  This means that we are permitted to
       // perform initialization with the address of the thunk.
-      if (Info.getLangOpts().CPlusPlus &&
-          !Info.keepEvaluatingAfterSideEffect() &&
-          FD->hasAttr<DLLImportAttr>())
+      if (Info.getLangOpts().CPlusPlus && FD->hasAttr<DLLImportAttr>())
         return false;
     }
   }
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -4193,7 +4193,7 @@
   if (Arg->isValueDependent() || Arg->isTypeDependent())
     return NPV_NotNullPointer;
   
-  if (!S.getLangOpts().CPlusPlus11)
+  if (!S.getLangOpts().CPlusPlus11 || S.getLangOpts().MSVCCompat)
     return NPV_NotNullPointer;
   
   // Determine whether we have a constant expression.
Index: test/CodeGenCXX/dllimport.cpp
===================================================================
--- test/CodeGenCXX/dllimport.cpp
+++ test/CodeGenCXX/dllimport.cpp
@@ -94,6 +94,14 @@
 };
 USE(inlineStaticLocalsFunc);
 
+// The address of a dllimport global cannot be used in constant initialization.
+// M32-DAG: @"\01?arr@?0??initializationFunc@@YAPAHXZ at 4QBQAHB" = internal global [1 x i32*] zeroinitializer
+// GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x i32*] zeroinitializer
+int *initializationFunc() {
+  static int *const arr[] = {&ExternGlobalDecl};
+  return arr[0];
+}
+USE(initializationFunc);
 
 
 //===----------------------------------------------------------------------===//
Index: test/Parser/MicrosoftExtensions.cpp
===================================================================
--- test/Parser/MicrosoftExtensions.cpp
+++ test/Parser/MicrosoftExtensions.cpp
@@ -118,7 +118,7 @@
 
 COM_CLASS_TEMPLATE_REF<int, __uuidof(struct_with_uuid)> good_template_arg;
 
-COM_CLASS_TEMPLATE<int, __uuidof(struct_with_uuid)> bad_template_arg; // expected-error {{non-type template argument of type 'const _GUID' is not a constant expression}}
+COM_CLASS_TEMPLATE<int, __uuidof(struct_with_uuid)> bad_template_arg; // expected-error {{non-type template argument of type 'const _GUID' cannot be converted to a value of type 'const GUID *' (aka 'const _GUID *')}}
 
 namespace PR16911 {
 struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid;
Index: test/SemaCXX/PR19955.cpp
===================================================================
--- test/SemaCXX/PR19955.cpp
+++ test/SemaCXX/PR19955.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-win32 -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple i686-win32 -fms-compatibility -verify -std=c++11 %s
 
 extern int __attribute__((dllimport)) var;
 constexpr int *varp = &var; // expected-error {{must be initialized by a constant expression}}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4299.10858.patch
Type: text/x-patch
Size: 3730 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140625/5e18560a/attachment.bin>


More information about the cfe-commits mailing list