rengolin created this revision. rengolin added reviewers: mcrosier, logan, asl. rengolin added subscribers: cfe-commits, llvm-commits. rengolin set the repository for this revision to rL LLVM.
Currently, for --rtlib=compiler-rt, when -lunwind or -lc++abi are in the arguments list, both libgcc_s and libgcc_eh are still added, which is wrong and duplicates symbols and may break stuff. This patch makes sure that, when adding compiler-rt companion libraries (unwind/c++), they haven't been added already. Repository: rL LLVM http://reviews.llvm.org/D11153 Files: lib/Driver/Tools.cpp test/Driver/linux-ld.c Index: test/Driver/linux-ld.c =================================================================== --- test/Driver/linux-ld.c +++ test/Driver/linux-ld.c @@ -1556,3 +1556,37 @@ // CHECK-ARMV7EB: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-ARMV7EB: "--be8" // CHECK-ARMV7EB: "-m" "armebelf_linux_eabi" + +// Test libunwind / libc++abi with compiler-rt +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// 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: --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: --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: --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 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,37 @@ // CHECK-ARMV7EB: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-ARMV7EB: "--be8" // CHECK-ARMV7EB: "-m" "armebelf_linux_eabi" + +// Test libunwind / libc++abi with compiler-rt +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o \ +// 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: --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: --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: --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 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,
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits