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@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}}
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@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}}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to