Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -2283,12 +2283,30 @@ ArgStringList &CmdArgs) { CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "builtins"))); - if (!TC.getTriple().isOSWindows()) { - // FIXME: why do we link against gcc when we are using compiler-rt? - CmdArgs.push_back("-lgcc_s"); - if (TC.getDriver().CCCIsCXX()) - CmdArgs.push_back("-lgcc_eh"); + if (TC.getTriple().isOSWindows()) + return; + + // FIXME: Get default library from each target/os. + // From here on, we assume this is a GNU target. Even if it's not GNU/Linux, + // the system toolchain is assumed GNU based, which could be wrong based on + // the OS and/or the Arch. + + // Get other libraries, to only include what's necessary and avoid + // duplication of symbols. + bool HasLibUnwind = false, HasLibCxxAbi = false; + for (const Arg *A : Args.filtered(options::OPT_l)) { + StringRef Value = A->getValue(); + if (Value == "unwind") + HasLibUnwind = true; + if (Value == "c++abi") + HasLibCxxAbi = true; } + // If we're including -lunwind, don't include -lgcc_s + if (!HasLibUnwind) + CmdArgs.push_back("-lgcc_s"); + // If we're including -lc++abi, don't include -lgcc_eh + if (!HasLibCxxAbi && TC.getDriver().CCCIsCXX()) + CmdArgs.push_back("-lgcc_eh"); } static void addProfileRT(const ToolChain &TC, const ArgList &Args, Index: test/Driver/linux-ld.c =================================================================== --- test/Driver/linux-ld.c +++ test/Driver/linux-ld.c @@ -1556,3 +1556,76 @@ // CHECK-ARMV7EB: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-ARMV7EB: "--be8" // CHECK-ARMV7EB: "-m" "armebelf_linux_eabi" + +// Test libunwind / libc++abi with compiler-rt (x86_64/ARM/AArch64) + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=x86_64-linux-gnu \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTGNU %s +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=x86_64-linux-gnu \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt -lunwind 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTUNW %s +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=x86_64-linux-gnu \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt -lc++abi 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTCXX %s +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=x86_64-linux-gnu \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt -lunwind -lc++abi 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTALL %s + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=armv7-linux-gnueabihf \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTGNU %s +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=armv7-linux-gnueabihf \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt -lunwind 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTUNW %s +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=armv7-linux-gnueabihf \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt -lc++abi 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTCXX %s +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=armv7-linux-gnueabihf \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt -lunwind -lc++abi 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTALL %s + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=aarch64-linux-gnu \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTGNU %s +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=aarch64-linux-gnu \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt -lunwind 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTUNW %s +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=aarch64-linux-gnu \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt -lc++abi 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTCXX %s +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// RUN: --target=aarch64-linux-gnu \ +// RUN: --driver-mode=g++ --rtlib=compiler-rt -lunwind -lc++abi 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-RTALL %s + +// CHECK-RTGNU: "{{.*}}ld{{(.exe)?}}" +// CHECK-RTGNU: "-lgcc_s" +// CHECK-RTGNU: libclang_rt.builtins-{{.*}}.a +// CHECK-RTGNU: "-lgcc_eh" + +// CHECK-RTUNW: "{{.*}}ld{{(.exe)?}}" +// CHECK-RTUNW: "-lunwind" +// CHECK-RTUNW: libclang_rt.builtins-{{.*}}.a +// CHECK-RTUNW: "-lgcc_eh" + +// CHECK-RTCXX: "{{.*}}ld{{(.exe)?}}" +// CHECK-RTCXX: "-lc++abi" +// CHECK-RTCXX: libclang_rt.builtins-{{.*}}.a +// CHECK-RTCXX: "-lgcc_s" + +// CHECK-RTALL: "{{.*}}ld{{(.exe)?}}" +// CHECK-RTALL: "-lunwind" +// CHECK-RTALL: "-lc++abi" +// CHECK-RTALL: libclang_rt.builtins-{{.*}}.a