diff options
author | Hans Wennborg <hans@hanshq.net> | 2014-06-25 22:19:48 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2014-06-25 22:19:48 +0000 |
commit | 7a08bd78a5be9410fa910961f001e157f68f2e6f (patch) | |
tree | 320b485d5c50cea95dba1bcd3fc6130a451b3035 | |
parent | 85fb905d517e07b0322fee8236e7b3314fb799aa (diff) | |
download | clang-7a08bd78a5be9410fa910961f001e157f68f2e6f.tar.gz clang-7a08bd78a5be9410fa910961f001e157f68f2e6f.tar.bz2 clang-7a08bd78a5be9410fa910961f001e157f68f2e6f.tar.xz |
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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211736 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/ExprConstant.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 2 | ||||
-rw-r--r-- | test/CodeGenCXX/dllimport.cpp | 8 | ||||
-rw-r--r-- | test/Parser/MicrosoftExtensions.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/PR19955.cpp | 2 |
5 files changed, 14 insertions, 13 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 5897f2c485..2803310c32 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -1275,13 +1275,8 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, 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 CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, // 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; } } diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 84c58d12ea..00d93f8528 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -4193,7 +4193,7 @@ isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param, 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. diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp index 63b119277e..d15eea24f2 100644 --- a/test/CodeGenCXX/dllimport.cpp +++ b/test/CodeGenCXX/dllimport.cpp @@ -94,6 +94,14 @@ inline int __declspec(dllimport) inlineStaticLocalsFunc() { }; 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); //===----------------------------------------------------------------------===// diff --git a/test/Parser/MicrosoftExtensions.cpp b/test/Parser/MicrosoftExtensions.cpp index 7f3ef6d903..076de7cd78 100644 --- a/test/Parser/MicrosoftExtensions.cpp +++ b/test/Parser/MicrosoftExtensions.cpp @@ -118,7 +118,7 @@ typedef COM_CLASS_TEMPLATE_REF<struct_with_uuid, __uuidof(struct_with_uuid)> COM 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; diff --git a/test/SemaCXX/PR19955.cpp b/test/SemaCXX/PR19955.cpp index 4596e5a459..fb1d74631b 100644 --- a/test/SemaCXX/PR19955.cpp +++ b/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}} |