nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1commit cd5603a4767277a29d3e67a9c3f2a5d2129cd973
2Author: Sterling Augustine <saugustine@google.com>
3Date: Tue Mar 19 20:01:59 2019 +0000
4
5 Add --unwindlib=[libgcc|compiler-rt] to parallel --rtlib= [take 2]
6
7 "clang++ hello.cc --rtlib=compiler-rt"
8
9 now can works without specifying additional unwind or exception
10 handling libraries.
11
12 This reworked version of the feature no longer modifies today's default
13 unwind library for compiler-rt: which is nothing. Rather, a user
14 can specify -DCLANG_DEFAULT_UNWINDLIB=libunwind when configuring
15 the compiler.
16
17 This should address the issues from the previous version.
18
19 Update tests for new --unwindlib semantics.
20
21 Differential Revision: https://reviews.llvm.org/D59109
22
23 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356508 91177308-0d34-0410-b5e6-96231b3b80d8
24 (cherry picked from commit 344aa82a52f2fae527f58284567ae305a314f7a8)
25
26diff --git a/CMakeLists.txt b/CMakeLists.txt
27index c2016a45ca..edeb2b66a1 100644
28--- a/CMakeLists.txt
29+++ b/CMakeLists.txt
30@@ -261,6 +261,24 @@ if (NOT(CLANG_DEFAULT_RTLIB STREQUAL "" OR
31 "Default runtime library to use (\"libgcc\" or \"compiler-rt\", empty for platform default)" FORCE)
32 endif()
33
34+set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
35+ "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty to match runtime library.)")
36+if (CLANG_DEFAULT_UNWINDLIB STREQUAL "")
37+ if (CLANG_DEFAULT_RTLIB STREQUAL "libgcc")
38+ set (CLANG_DEFAULT_UNWINDLIB "libgcc" CACHE STRING "" FORCE)
39+ elseif (CLANG_DEFAULT_RTLIBS STREQUAL "libunwind")
40+ set (CLANG_DEFAULT_UNWINDLIB "none" CACHE STRING "" FORCE)
41+ endif()
42+endif()
43+
44+if (NOT(CLANG_DEFAULT_UNWINDLIB STREQUAL "none" OR
45+ CLANG_DEFAULT_UNWINDLIB STREQUAL "libgcc" OR
46+ CLANG_DEFAULT_UNWINDLIB STREQUAL "libunwind"))
47+ message(WARNING "Resetting default unwindlib to use platform default")
48+ set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
49+ "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty for none)" FORCE)
50+endif()
51+
52 set(CLANG_DEFAULT_OBJCOPY "objcopy" CACHE STRING
53 "Default objcopy executable to use.")
54
55diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
56index 5475e28ed7..15971210e4 100644
57--- a/include/clang/Basic/DiagnosticDriverKinds.td
58+++ b/include/clang/Basic/DiagnosticDriverKinds.td
59@@ -52,6 +52,10 @@ def err_drv_invalid_rtlib_name : Error<
60 "invalid runtime library name in argument '%0'">;
61 def err_drv_unsupported_rtlib_for_platform : Error<
62 "unsupported runtime library '%0' for platform '%1'">;
63+def err_drv_invalid_unwindlib_name : Error<
64+ "invalid unwind library name in argument '%0'">;
65+def err_drv_incompatible_unwindlib : Error<
66+ "--rtlib=libgcc requires --unwindlib=libgcc">;
67 def err_drv_invalid_stdlib_name : Error<
68 "invalid library name in argument '%0'">;
69 def err_drv_invalid_output_with_multiple_archs : Error<
70diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
71index 1d624450b9..2d4cb747e8 100644
72--- a/include/clang/Config/config.h.cmake
73+++ b/include/clang/Config/config.h.cmake
74@@ -23,6 +23,9 @@
75 /* Default runtime library to use. */
76 #define CLANG_DEFAULT_RTLIB "${CLANG_DEFAULT_RTLIB}"
77
78+/* Default unwind library to use. */
79+#define CLANG_DEFAULT_UNWINDLIB "${CLANG_DEFAULT_UNWINDLIB}"
80+
81 /* Default objcopy to use */
82 #define CLANG_DEFAULT_OBJCOPY "${CLANG_DEFAULT_OBJCOPY}"
83
84diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
85index 75a21e66c7..4da0e54965 100644
86--- a/include/clang/Driver/Options.td
87+++ b/include/clang/Driver/Options.td
88@@ -2570,6 +2570,8 @@ def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>,
89 }]>;
90 def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>,
91 HelpText<"C++ standard library to use">, Values<"libc++,libstdc++,platform">;
92+def unwindlib_EQ : Joined<["-", "--"], "unwindlib=">, Flags<[CC1Option]>,
93+ HelpText<"Unwind library to use">, Values<"libgcc,unwindlib,platform">;
94 def sub__library : JoinedOrSeparate<["-"], "sub_library">;
95 def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">;
96 def system_header_prefix : Joined<["--"], "system-header-prefix=">,
97diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
98index d5f75b8271..4bedf760eb 100644
99--- a/include/clang/Driver/ToolChain.h
100+++ b/include/clang/Driver/ToolChain.h
101@@ -100,6 +100,12 @@ public:
102 RLT_Libgcc
103 };
104
105+ enum UnwindLibType {
106+ UNW_None,
107+ UNW_CompilerRT,
108+ UNW_Libgcc
109+ };
110+
111 enum RTTIMode {
112 RM_Enabled,
113 RM_Disabled,
114@@ -368,6 +374,10 @@ public:
115 return ToolChain::CST_Libstdcxx;
116 }
117
118+ virtual UnwindLibType GetDefaultUnwindLibType() const {
119+ return ToolChain::UNW_None;
120+ }
121+
122 virtual std::string getCompilerRTPath() const;
123
124 virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
125@@ -512,6 +522,10 @@ public:
126 // given compilation arguments.
127 virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
128
129+ // GetUnwindLibType - Determine the unwind library type to use with the
130+ // given compilation arguments.
131+ virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const;
132+
133 /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
134 /// the include paths to use for the given C++ standard library type.
135 virtual void
136diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
137index 88a627eab6..d82423f4a8 100644
138--- a/lib/Driver/ToolChain.cpp
139+++ b/lib/Driver/ToolChain.cpp
140@@ -680,6 +680,33 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
141 return GetDefaultRuntimeLibType();
142 }
143
144+ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
145+ const ArgList &Args) const {
146+ const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
147+ StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
148+
149+ if (LibName == "none")
150+ return ToolChain::UNW_None;
151+ else if (LibName == "platform" || LibName == "") {
152+ ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
153+ if (RtLibType == ToolChain::RLT_CompilerRT)
154+ return ToolChain::UNW_None;
155+ else if (RtLibType == ToolChain::RLT_Libgcc)
156+ return ToolChain::UNW_Libgcc;
157+ } else if (LibName == "libunwind") {
158+ if (GetRuntimeLibType(Args) == RLT_Libgcc)
159+ getDriver().Diag(diag::err_drv_incompatible_unwindlib);
160+ return ToolChain::UNW_CompilerRT;
161+ } else if (LibName == "libgcc")
162+ return ToolChain::UNW_Libgcc;
163+
164+ if (A)
165+ getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
166+ << A->getAsString(Args);
167+
168+ return GetDefaultUnwindLibType();
169+}
170+
171 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
172 const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
173 StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
174diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp
175index 85ffc1618d..9fd29726a4 100644
176--- a/lib/Driver/ToolChains/CommonArgs.cpp
177+++ b/lib/Driver/ToolChains/CommonArgs.cpp
178@@ -1132,47 +1132,80 @@ bool tools::isObjCAutoRefCount(const ArgList &Args) {
179 return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
180 }
181
182-static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
183- ArgStringList &CmdArgs, const ArgList &Args) {
184- bool isAndroid = Triple.isAndroid();
185- bool isCygMing = Triple.isOSCygMing();
186- bool IsIAMCU = Triple.isOSIAMCU();
187- bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
188- Args.hasArg(options::OPT_static) ||
189- Args.hasArg(options::OPT_static_pie);
190-
191- bool SharedLibgcc = Args.hasArg(options::OPT_shared_libgcc);
192- bool UnspecifiedLibgcc = !StaticLibgcc && !SharedLibgcc;
193-
194- // Gcc adds libgcc arguments in various ways:
195- //
196- // gcc <none>: -lgcc --as-needed -lgcc_s --no-as-needed
197- // g++ <none>: -lgcc_s -lgcc
198- // gcc shared: -lgcc_s -lgcc
199- // g++ shared: -lgcc_s -lgcc
200- // gcc static: -lgcc -lgcc_eh
201- // g++ static: -lgcc -lgcc_eh
202- // gcc static-pie: -lgcc -lgcc_eh
203- // g++ static-pie: -lgcc -lgcc_eh
204- //
205- // Also, certain targets need additional adjustments.
206+enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc };
207+
208+static LibGccType getLibGccType(const ArgList &Args) {
209+ bool Static = Args.hasArg(options::OPT_static_libgcc) ||
210+ Args.hasArg(options::OPT_static) ||
211+ Args.hasArg(options::OPT_static_pie);
212+
213+ bool Shared = Args.hasArg(options::OPT_shared_libgcc);
214+ if (Shared)
215+ return LibGccType::SharedLibGcc;
216+ if (Static)
217+ return LibGccType::StaticLibGcc;
218+ return LibGccType::UnspecifiedLibGcc;
219+}
220
221- bool LibGccFirst = (D.CCCIsCC() && UnspecifiedLibgcc) || StaticLibgcc;
222- if (LibGccFirst)
223- CmdArgs.push_back("-lgcc");
224+// Gcc adds libgcc arguments in various ways:
225+//
226+// gcc <none>: -lgcc --as-needed -lgcc_s --no-as-needed
227+// g++ <none>: -lgcc_s -lgcc
228+// gcc shared: -lgcc_s -lgcc
229+// g++ shared: -lgcc_s -lgcc
230+// gcc static: -lgcc -lgcc_eh
231+// g++ static: -lgcc -lgcc_eh
232+// gcc static-pie: -lgcc -lgcc_eh
233+// g++ static-pie: -lgcc -lgcc_eh
234+//
235+// Also, certain targets need additional adjustments.
236+
237+static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
238+ ArgStringList &CmdArgs, const ArgList &Args) {
239+ ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args);
240+ // Targets that don't use unwind libraries.
241+ if (TC.getTriple().isAndroid() || TC.getTriple().isOSIAMCU() ||
242+ TC.getTriple().isOSBinFormatWasm() ||
243+ UNW == ToolChain::UNW_None)
244+ return;
245
246- bool AsNeeded = D.CCCIsCC() && UnspecifiedLibgcc && !isAndroid && !isCygMing;
247+ LibGccType LGT = getLibGccType(Args);
248+ bool AsNeeded = D.CCCIsCC() && LGT == LibGccType::UnspecifiedLibGcc &&
249+ !TC.getTriple().isAndroid() && !TC.getTriple().isOSCygMing();
250 if (AsNeeded)
251 CmdArgs.push_back("--as-needed");
252
253- if ((UnspecifiedLibgcc || SharedLibgcc) && !isAndroid)
254- CmdArgs.push_back("-lgcc_s");
255-
256- else if (StaticLibgcc && !isAndroid && !IsIAMCU)
257- CmdArgs.push_back("-lgcc_eh");
258+ switch (UNW) {
259+ case ToolChain::UNW_None:
260+ return;
261+ case ToolChain::UNW_Libgcc: {
262+ LibGccType LGT = getLibGccType(Args);
263+ if (LGT == LibGccType::UnspecifiedLibGcc || LGT == LibGccType::SharedLibGcc)
264+ CmdArgs.push_back("-lgcc_s");
265+ else if (LGT == LibGccType::StaticLibGcc)
266+ CmdArgs.push_back("-lgcc_eh");
267+ break;
268+ }
269+ case ToolChain::UNW_CompilerRT:
270+ CmdArgs.push_back("-lunwind");
271+ break;
272+ }
273
274 if (AsNeeded)
275 CmdArgs.push_back("--no-as-needed");
276+}
277+
278+static void AddLibgcc(const ToolChain &TC, const Driver &D,
279+ ArgStringList &CmdArgs, const ArgList &Args) {
280+ bool isAndroid = TC.getTriple().isAndroid();
281+
282+ LibGccType LGT = getLibGccType(Args);
283+ bool LibGccFirst = (D.CCCIsCC() && LGT == LibGccType::UnspecifiedLibGcc) ||
284+ LGT == LibGccType::StaticLibGcc;
285+ if (LibGccFirst)
286+ CmdArgs.push_back("-lgcc");
287+
288+ AddUnwindLibrary(TC, D, CmdArgs, Args);
289
290 if (!LibGccFirst)
291 CmdArgs.push_back("-lgcc");
292@@ -1182,7 +1215,7 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
293 //
294 // NOTE: This fixes a link error on Android MIPS as well. The non-static
295 // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
296- if (isAndroid && !StaticLibgcc)
297+ if (isAndroid && getLibGccType(Args) != LibGccType::StaticLibGcc)
298 CmdArgs.push_back("-ldl");
299 }
300
301@@ -1194,6 +1227,7 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
302 switch (RLT) {
303 case ToolChain::RLT_CompilerRT:
304 CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
305+ AddUnwindLibrary(TC, D, CmdArgs, Args);
306 break;
307 case ToolChain::RLT_Libgcc:
308 // Make sure libgcc is not used under MSVC environment by default
309@@ -1205,7 +1239,7 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
310 << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "MSVC";
311 }
312 } else
313- AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
314+ AddLibgcc(TC, D, CmdArgs, Args);
315 break;
316 }
317 }
318diff --git a/test/Driver/compiler-rt-unwind.c b/test/Driver/compiler-rt-unwind.c
319new file mode 100644
320index 0000000000..00024dfa7e
321--- /dev/null
322+++ b/test/Driver/compiler-rt-unwind.c
323@@ -0,0 +1,49 @@
324+// General tests that the driver handles combinations of --rtlib=XXX and
325+// --unwindlib=XXX properly.
326+//
327+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
328+// RUN: --target=x86_64-unknown-linux \
329+// RUN: --gcc-toolchain="" \
330+// RUN: | FileCheck --check-prefix=RTLIB-EMPTY %s
331+// RTLIB-EMPTY: "{{.*}}lgcc"
332+// RTLIB-EMPTY: "{{.*}}-lgcc_s"
333+//
334+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
335+// RUN: --target=x86_64-unknown-linux -rtlib=libgcc \
336+// RUN: --gcc-toolchain="" \
337+// RUN: | FileCheck --check-prefix=RTLIB-GCC %s
338+// RTLIB-GCC: "{{.*}}lgcc"
339+// RTLIB-GCC: "{{.*}}lgcc_s"
340+//
341+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
342+// RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
343+// RUN: --gcc-toolchain="" \
344+// RUN: | FileCheck --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER-RT %s
345+// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lgcc"
346+// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lunwind"
347+//
348+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
349+// RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt \
350+// RUN: --gcc-toolchain="" \
351+// RUN: | FileCheck --check-prefix=RTLIB-COMPILER-RT %s
352+// RTLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a"
353+//
354+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
355+// RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
356+// RUN: --gcc-toolchain="" \
357+// RUN: | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC %s
358+// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}libclang_rt.builtins-x86_64.a"
359+// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}lgcc_s"
360+//
361+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
362+// RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
363+// RUN: -static --gcc-toolchain="" \
364+// RUN: | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC %s
365+// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}libclang_rt.builtins-x86_64.a"
366+// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}lgcc_eh"
367+//
368+// RUN: not %clang -no-canonical-prefixes %s -o %t.o 2> %t.err \
369+// RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
370+// RUN: --gcc-toolchain="" \
371+// RUN: FileCheck --input-file=%t.err --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER_RT %s
372+// RTLIB-GCC-UNWINDLIB-COMPILER_RT: "{{[.|\\\n]*}}--rtlib=libgcc requires --unwindlib=libgcc"