summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2014-06-25 22:19:48 +0000
committerHans Wennborg <hans@hanshq.net>2014-06-25 22:19:48 +0000
commit82dd877e8a4fe1cbab27be2b067fe7724a07a875 (patch)
treec0583393230e9037ebcac23a151c94417ea49892 /clang
parentc010ddb73db9a3a89ff65fb2a653daeae3744d86 (diff)
downloadbcm5719-llvm-82dd877e8a4fe1cbab27be2b067fe7724a07a875.tar.gz
bcm5719-llvm-82dd877e8a4fe1cbab27be2b067fe7724a07a875.zip
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 llvm-svn: 211736
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/ExprConstant.cpp13
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp2
-rw-r--r--clang/test/CodeGenCXX/dllimport.cpp8
-rw-r--r--clang/test/Parser/MicrosoftExtensions.cpp2
-rw-r--r--clang/test/SemaCXX/PR19955.cpp2
5 files changed, 14 insertions, 13 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 5897f2c4856..2803310c325 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/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/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 84c58d12ea8..00d93f85280 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/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/clang/test/CodeGenCXX/dllimport.cpp b/clang/test/CodeGenCXX/dllimport.cpp
index 63b119277ec..d15eea24f2f 100644
--- a/clang/test/CodeGenCXX/dllimport.cpp
+++ b/clang/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/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp
index 7f3ef6d903c..076de7cd785 100644
--- a/clang/test/Parser/MicrosoftExtensions.cpp
+++ b/clang/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/clang/test/SemaCXX/PR19955.cpp b/clang/test/SemaCXX/PR19955.cpp
index 4596e5a459e..fb1d74631b2 100644
--- a/clang/test/SemaCXX/PR19955.cpp
+++ b/clang/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}}
OpenPOWER on IntegriCloud