r211736 - Don't allow dllimport variables in constant initializers

Hans Wennborg hans at hanshq.net
Wed Jun 25 15:19:49 PDT 2014


Author: hans
Date: Wed Jun 25 17:19:48 2014
New Revision: 211736

URL: http://llvm.org/viewvc/llvm-project?rev=211736&view=rev
Log:
Don't allow dllimport variables in constant initializers

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.

  __declspec(dllimport) extern const char foo[];
  const char* f() {
    static const char* const arr[] = { foo };
    return arr[0];
  }

Differential Revision: http://reviews.llvm.org/D4299

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

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=211736&r1=211735&r2=211736&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Jun 25 17:19:48 2014
@@ -1275,13 +1275,8 @@ static bool CheckLValueConstantExpressio
       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 @@ static bool CheckLValueConstantExpressio
       // 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;
     }
   }

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=211736&r1=211735&r2=211736&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Jun 25 17:19:48 2014
@@ -4193,7 +4193,7 @@ isNullPointerValueTemplateArgument(Sema
   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.

Modified: cfe/trunk/test/CodeGenCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllimport.cpp?rev=211736&r1=211735&r2=211736&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/dllimport.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/dllimport.cpp Wed Jun 25 17:19:48 2014
@@ -94,6 +94,14 @@ inline int __declspec(dllimport) inlineS
 };
 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);
 
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=211736&r1=211735&r2=211736&view=diff
==============================================================================
--- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Wed Jun 25 17:19:48 2014
@@ -118,7 +118,7 @@ typedef COM_CLASS_TEMPLATE_REF<struct_wi
 
 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;

Modified: cfe/trunk/test/SemaCXX/PR19955.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/PR19955.cpp?rev=211736&r1=211735&r2=211736&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/PR19955.cpp (original)
+++ cfe/trunk/test/SemaCXX/PR19955.cpp Wed Jun 25 17:19:48 2014
@@ -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}}





More information about the cfe-commits mailing list