Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -3000,9 +3000,13 @@ if (F->empty()) { F->setCallingConv(getRuntimeCC()); - if (!Local && getTriple().isOSBinFormatCOFF() && - !getCodeGenOpts().LTOVisibilityPublicStd && - !getTriple().isWindowsGNUEnvironment()) { + // In Windows Itanium environments, try to mark runtime functions + // dllimport. For Mingw and MSVC, don't. We don't really know if the user + // will link their standard library statically or dynamically. Marking + // functions imported when they are not imported can cause linker errors + // and warnings. + if (!Local && getTriple().isWindowsItaniumEnvironment() && + !getCodeGenOpts().LTOVisibilityPublicStd) { const FunctionDecl *FD = GetRuntimeFunctionDecl(Context, Name); if (!FD || FD->hasAttr()) { F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); Index: test/CodeGenCXX/dllimport-runtime-fns.cpp =================================================================== --- test/CodeGenCXX/dllimport-runtime-fns.cpp +++ test/CodeGenCXX/dllimport-runtime-fns.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -fms-extensions -fms-compatibility-version=19.20 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=MSVC +// RUN: %clang_cc1 -fms-extensions -fms-compatibility-version=19.20 -triple aarch64-windows-msvc -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=MSVC +// RUN: %clang_cc1 -triple x86_64-windows-itanium -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=ITANIUM +// RUN: %clang_cc1 -triple aarch64-windows-gnu -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=GNU + +void foo1() { throw 1; } +// _CxxThrowException should not be marked dllimport. +// MSVC-LABEL: define dso_local void @"?foo1@@YAXXZ" +// MSVC: call void @_CxxThrowException +// MSVC: declare dso_local void @_CxxThrowException(i8*, %eh.ThrowInfo*) + +// __cxa_throw should be marked dllimport for *-windows-itanium. +// ITANIUM-LABEL: define dso_local void @_Z4foo1v() +// ITANIUM: call void @__cxa_throw({{.*}}) +// ITANIUM: declare dllimport void @__cxa_throw({{.*}}) + +// ... but not for *-windows-gnu. +// GNU-LABEL: define dso_local void @_Z4foo1v() +// GNU: call void @__cxa_throw({{.*}}) +// GNU: declare dso_local void @__cxa_throw({{.*}}) + + +void bar(); +void foo2() noexcept(true) { bar(); } +// __std_terminate should not be marked dllimport. +// MSVC-LABEL: define dso_local void @"?foo2@@YAXXZ" +// MSVC: call void @__std_terminate() +// MSVC: declare dso_local void @__std_terminate() + +// _ZSt9terminatev and __cxa_begin_catch should be marked dllimport. +// ITANIUM-LABEL: define linkonce_odr hidden void @__clang_call_terminate(i8*) +// ITANIUM: call i8* @__cxa_begin_catch({{.*}}) +// ITANIUM: call void @_ZSt9terminatev() +// ITANIUM: declare dllimport i8* @__cxa_begin_catch(i8*) +// ITANIUM: declare dllimport void @_ZSt9terminatev() + +// .. not for mingw. +// GNU-LABEL: define linkonce_odr hidden void @__clang_call_terminate(i8*) +// GNU: call i8* @__cxa_begin_catch({{.*}}) +// GNU: call void @_ZSt9terminatev() +// GNU: declare dso_local i8* @__cxa_begin_catch(i8*) +// GNU: declare dso_local void @_ZSt9terminatev() + + +struct A {}; +struct B { virtual void f(); }; +struct C : A, virtual B {}; +struct T {}; +T *foo3() { return dynamic_cast((C *)0); } +// __RTDynamicCast should not be marked dllimport. +// MSVC-LABEL: define dso_local %struct.T* @"?foo3@@YAPEAUT@@XZ" +// MSVC: call i8* @__RTDynamicCast({{.*}}) +// MSVC: declare dso_local i8* @__RTDynamicCast(i8*, i32, i8*, i8*, i32) + +// Again, imported +// ITANIUM-LABEL: define dso_local %struct.T* @_Z4foo3v() +// ITANIUM: call i8* @__dynamic_cast({{.*}}) +// ITANIUM: declare dllimport i8* @__dynamic_cast({{.*}}) + +// Not imported +// GNU-LABEL: define dso_local %struct.T* @_Z4foo3v() +// GNU: call i8* @__dynamic_cast({{.*}}) +// GNU: declare dso_local i8* @__dynamic_cast({{.*}}) Index: test/CodeGenCXX/runtime-dllstorage.cpp =================================================================== --- test/CodeGenCXX/runtime-dllstorage.cpp +++ test/CodeGenCXX/runtime-dllstorage.cpp @@ -14,7 +14,7 @@ // RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA // RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA +// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA // RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA #if defined(IMPORT_DECLARATIONS) @@ -108,7 +108,7 @@ // CHECK-MS-DAG: @_Init_thread_epoch = external thread_local global i32 // CHECK-MS-DAG: declare dso_local i32 @__tlregdtor(void ()*) // CHECK-MS-DAG: declare dso_local i32 @atexit(void ()*) -// CHECK-MS-DYNAMIC-DAG: declare dllimport {{.*}} void @_CxxThrowException +// CHECK-MS-DYNAMIC-DAG: declare {{.*}} void @_CxxThrowException // CHECK-MS-STATIC-DAG: declare {{.*}} void @_CxxThrowException // CHECK-MS-DAG: declare dso_local noalias i8* @"??2@YAPAXI@Z" // CHECK-MS-DAG: declare dso_local void @_Init_thread_header(i32*) Index: test/CodeGenObjC/gnu-init.m =================================================================== --- test/CodeGenObjC/gnu-init.m +++ test/CodeGenObjC/gnu-init.m @@ -100,6 +100,6 @@ // Check our load function is in a comdat. // CHECK-WIN: define linkonce_odr hidden void @.objcv2_load_function() comdat { -// Make sure we have dllimport on the load function -// CHECK-WIN: declare dllimport void @__objc_load +// Make sure we do not have dllimport on the load function +// CHECK-WIN: declare dso_local void @__objc_load Index: test/CodeGenObjCXX/msabi-stret.mm =================================================================== --- test/CodeGenObjCXX/msabi-stret.mm +++ test/CodeGenObjCXX/msabi-stret.mm @@ -13,6 +13,5 @@ return [I m:S()]; } -// CHECK: declare dllimport void @objc_msgSend_stret(i8*, i8*, ...) +// CHECK: declare dso_local void @objc_msgSend_stret(i8*, i8*, ...) // CHECK-NOT: declare dllimport void @objc_msgSend(i8*, i8*, ...) -