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