Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -2228,12 +2228,16 @@ // FIXME: Diagnostic! return false; - // A dllimport variable never acts like a constant, unless we're - // evaluating a value for use only in name mangling. - if (!isForManglingOnly(Kind) && Var->hasAttr()) + if (!isForManglingOnly(Kind) && Var->hasAttr()) { // FIXME: Diagnostic! - return false; - + if (Info.getLangOpts().C99) + // Address of dllimport variables can't be used for initialization in + // C language modes. + return false; + // A dllimport variable can be a constant address. This is a MS + // extension. + return true; + } // In CUDA/HIP device compilation, only device side variables have // constant addresses. if (Info.getCtx().getLangOpts().CUDA && Index: clang/test/CodeGenCXX/PR19955.cpp =================================================================== --- clang/test/CodeGenCXX/PR19955.cpp +++ clang/test/CodeGenCXX/PR19955.cpp @@ -6,20 +6,15 @@ extern int *varp; int *varp = &var; -// CHECK-DAG: @"?varp@@3PAHA" = dso_local global ptr null -// X64-DAG: @"?varp@@3PEAHEA" = dso_local global ptr null +// CHECK-DAG: @"?var@@3HA" = external dllimport global i32 +// CHECK-DAG: @"?varp@@3PAHA" = dso_local global ptr @"?var@@3HA" + extern void (*funp)(); void (*funp)() = &fun; // CHECK-DAG: @"?funp@@3P6AXXZA" = dso_local global ptr null // X64-DAG: @"?funp@@3P6AXXZEA" = dso_local global ptr null -// CHECK-LABEL: @"??__Evarp@@YAXXZ" -// CHECK-DAG: store ptr @"?var@@3HA", ptr @"?varp@@3PAHA" - -// X64-LABEL: @"??__Evarp@@YAXXZ" -// X64-DAG: store ptr @"?var@@3HA", ptr @"?varp@@3PEAHEA" - // CHECK-LABEL: @"??__Efunp@@YAXXZ"() // CHECK-DAG: store ptr @"?fun@@YAXXZ", ptr @"?funp@@3P6AXXZA" Index: clang/test/CodeGenCXX/dllimport.cpp =================================================================== --- clang/test/CodeGenCXX/dllimport.cpp +++ clang/test/CodeGenCXX/dllimport.cpp @@ -97,9 +97,9 @@ }; USE(inlineStaticLocalsFunc); -// The address of a dllimport global cannot be used in constant initialization. -// M32-DAG: @"?arr@?1??initializationFunc@@YAPAHXZ@4QBQAHB" = internal global [1 x ptr] zeroinitializer -// GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x ptr] zeroinitializer +// The address of a dllimport global can be used in constant initialization. +// M32-DAG: @"?arr@?1??initializationFunc@@YAPAHXZ@4QBQAHB" = internal constant [1 x ptr] [ptr @"?ExternGlobalDecl@@3HA"] +// GNU-DAG: @_ZZ18initializationFuncvE3arr = internal constant [1 x ptr] [ptr @ExternGlobalDecl] int *initializationFunc() { static int *const arr[] = {&ExternGlobalDecl}; return arr[0]; Index: clang/test/SemaCXX/PR19955.cpp =================================================================== --- clang/test/SemaCXX/PR19955.cpp +++ clang/test/SemaCXX/PR19955.cpp @@ -2,7 +2,7 @@ // RUN: %clang_cc1 -triple i686-mingw32 -verify -std=c++11 %s extern int __attribute__((dllimport)) var; -constexpr int *varp = &var; // expected-error {{must be initialized by a constant expression}} +constexpr int *varp = &var; extern __attribute__((dllimport)) void fun(); constexpr void (*funp)(void) = &fun; // expected-error {{must be initialized by a constant expression}} Index: clang/test/SemaCXX/dllimport-constexpr.cpp =================================================================== --- clang/test/SemaCXX/dllimport-constexpr.cpp +++ clang/test/SemaCXX/dllimport-constexpr.cpp @@ -40,7 +40,6 @@ // constexpr initialization doesn't work for dllimport things. // expected-error@+1{{must be initialized by a constant expression}} constexpr void (*constexpr_import_func)() = &imported_func; -// expected-error@+1{{must be initialized by a constant expression}} constexpr int *constexpr_import_int = &imported_int; // expected-error@+1{{must be initialized by a constant expression}} constexpr void (Foo::*constexpr_memptr)() = &Foo::imported_method;