Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -2213,7 +2213,10 @@ // 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 (Info.getLangOpts().C99 && !isForManglingOnly(Kind) && + Var->hasAttr() || + Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) && + Var->hasAttr()) // FIXME: Diagnostic! return false; } Index: clang/test/CodeGenCXX/PR19955.cpp =================================================================== --- clang/test/CodeGenCXX/PR19955.cpp +++ clang/test/CodeGenCXX/PR19955.cpp @@ -6,20 +6,16 @@ extern int *varp; int *varp = &var; -// CHECK-DAG: @"?varp@@3PAHA" = dso_local global i32* null -// X64-DAG: @"?varp@@3PEAHEA" = dso_local global i32* null +// CHECK-DAG: @"?var@@3HA" = external dllimport global i32 +// CHECK-DAG: @"?varp@@3PAHA" = dso_local global i32* @"?var@@3HA" +// X64-DAG: @"?var@@3HA" = external dllimport global i32, align 4 +// X64-DAG: @"?varp@@3PEAHEA" = dso_local global i32* @"?var@@3HA" extern void (*funp)(); void (*funp)() = &fun; // CHECK-DAG: @"?funp@@3P6AXXZA" = dso_local global void ()* null // X64-DAG: @"?funp@@3P6AXXZEA" = dso_local global void ()* null -// CHECK-LABEL: @"??__Evarp@@YAXXZ" -// CHECK-DAG: store i32* @"?var@@3HA", i32** @"?varp@@3PAHA" - -// X64-LABEL: @"??__Evarp@@YAXXZ" -// X64-DAG: store i32* @"?var@@3HA", i32** @"?varp@@3PEAHEA" - // CHECK-LABEL: @"??__Efunp@@YAXXZ"() // CHECK-DAG: store void ()* @"?fun@@YAXXZ", void ()** @"?funp@@3P6AXXZA" Index: clang/test/CodeGenCXX/dllimport.cpp =================================================================== --- clang/test/CodeGenCXX/dllimport.cpp +++ clang/test/CodeGenCXX/dllimport.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -disable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M32 %s -// RUN: %clang_cc1 -disable-noundef-analysis -triple x86_64-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s +// RUN: %clang_cc1 -disable-noundef-analysis -triple x86_64-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC64 --check-prefix=M64 %s // RUN: %clang_cc1 -disable-noundef-analysis -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s // RUN: %clang_cc1 -disable-noundef-analysis -triple x86_64-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU %s // RUN: %clang_cc1 -disable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s @@ -39,30 +39,34 @@ // Import declaration. // MSC-DAG: @"?ExternGlobalDecl@@3HA" = external dllimport global i32 +// MSC64-DAG: @"?ExternGlobalDecl@@3HA" = external dllimport global i32 // GNU-DAG: @ExternGlobalDecl = external dllimport global i32 __declspec(dllimport) extern int ExternGlobalDecl; USEVAR(ExternGlobalDecl) // dllimport implies a declaration. // MSC-DAG: @"?GlobalDecl@@3HA" = external dllimport global i32 +// MSC64-DAG: @"?GlobalDecl@@3HA" = external dllimport global i32 // GNU-DAG: @GlobalDecl = external dllimport global i32 __declspec(dllimport) int GlobalDecl; USEVAR(GlobalDecl) // Redeclarations // MSC-DAG: @"?GlobalRedecl1@@3HA" = external dllimport global i32 +// MSC64-DAG: @"?GlobalRedecl1@@3HA" = external dllimport global i32 // GNU-DAG: @GlobalRedecl1 = external dllimport global i32 __declspec(dllimport) extern int GlobalRedecl1; __declspec(dllimport) extern int GlobalRedecl1; USEVAR(GlobalRedecl1) // MSC-DAG: @"?GlobalRedecl2a@@3HA" = external dllimport global i32 +// MSC64-DAG: @"?GlobalRedecl2a@@3HA" = external dllimport global i32 // GNU-DAG: @GlobalRedecl2a = external dllimport global i32 __declspec(dllimport) int GlobalRedecl2a; __declspec(dllimport) int GlobalRedecl2a; USEVAR(GlobalRedecl2a) -// M32-DAG: @"?GlobalRedecl2b@@3PAHA" = external dllimport global i32* +// MSC-DAG: @"?GlobalRedecl2b@@3PAHA" = external dllimport global i32* // M64-DAG: @"?GlobalRedecl2b@@3PEAHEA" = external dllimport global i32* // GNU-DAG: @GlobalRedecl2b = external dllimport global i32* int *__attribute__((dllimport)) GlobalRedecl2b; @@ -98,8 +102,8 @@ 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 i32*] zeroinitializer -// GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x i32*] zeroinitializer +// M32-DAG: @"?arr@?1??initializationFunc@@YAPAHXZ@4QBQAHB" = internal constant [1 x i32*] [i32* @"?ExternGlobalDecl@@3HA"] +// GNU-DAG: @_ZZ18initializationFuncvE3arr = internal constant [1 x i32*] [i32* @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; @@ -60,3 +59,8 @@ // expected-note@+1 {{requested here}} StaticConstexpr::g_fp(); } + +void foo() { + extern int __declspec(dllimport) dll_import_int; + constexpr int& dll_import_constexpr_ref = dll_import_int; +}