Index: cfe/trunk/lib/AST/ExprConstant.cpp =================================================================== --- cfe/trunk/lib/AST/ExprConstant.cpp +++ cfe/trunk/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()) + // A dllimport variable never acts like a constant. + if (Var->hasAttr()) return false; } if (const auto *FD = dyn_cast(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()) + if (Info.getLangOpts().CPlusPlus && FD->hasAttr()) return false; } } Index: cfe/trunk/lib/Sema/SemaTemplate.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp +++ cfe/trunk/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: cfe/trunk/test/CodeGenCXX/dllimport.cpp =================================================================== --- cfe/trunk/test/CodeGenCXX/dllimport.cpp +++ cfe/trunk/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: cfe/trunk/test/Parser/MicrosoftExtensions.cpp =================================================================== --- cfe/trunk/test/Parser/MicrosoftExtensions.cpp +++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp @@ -118,7 +118,7 @@ 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; Index: cfe/trunk/test/SemaCXX/PR19955.cpp =================================================================== --- cfe/trunk/test/SemaCXX/PR19955.cpp +++ cfe/trunk/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}}