summaryrefslogtreecommitdiff
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
commit7a08bd78a5be9410fa910961f001e157f68f2e6f (patch)
tree320b485d5c50cea95dba1bcd3fc6130a451b3035
parent85fb905d517e07b0322fee8236e7b3314fb799aa (diff)
downloadclang-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.cpp13
-rw-r--r--lib/Sema/SemaTemplate.cpp2
-rw-r--r--test/CodeGenCXX/dllimport.cpp8
-rw-r--r--test/Parser/MicrosoftExtensions.cpp2
-rw-r--r--test/SemaCXX/PR19955.cpp2
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}}