diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 5897f2c48569..2803310c3256 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()) + // A dllimport variable never acts like a constant. + if (Var->hasAttr()) return false; } if (const auto *FD = dyn_cast(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()) + if (Info.getLangOpts().CPlusPlus && FD->hasAttr()) return false; } } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 84c58d12ea8e..00d93f852808 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 63b119277eca..d15eea24f2f5 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 7f3ef6d903c4..076de7cd785c 100644 --- a/clang/test/Parser/MicrosoftExtensions.cpp +++ b/clang/test/Parser/MicrosoftExtensions.cpp @@ -118,7 +118,7 @@ typedef COM_CLASS_TEMPLATE_REF COM COM_CLASS_TEMPLATE_REF good_template_arg; -COM_CLASS_TEMPLATE bad_template_arg; // expected-error {{non-type template argument of type 'const _GUID' is not a constant expression}} +COM_CLASS_TEMPLATE 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 4596e5a459e4..fb1d74631b2b 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}}