about summary refs log tree commit diff
path: root/nixpkgs/pkgs/development/compilers/llvm/7/clang/unwindlib.patch
blob: 59a092d7c706953498743a3da391931d6e34dcc7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
commit a5cacb5ba7f1f18e7bb6f6709e42683eeb7e6470
Author: Sterling Augustine <saugustine@google.com>
Date:   Tue Mar 19 20:01:59 2019 +0000

    Add --unwindlib=[libgcc|compiler-rt] to parallel --rtlib= [take 2]
    
    "clang++ hello.cc --rtlib=compiler-rt"
    
    now can works without specifying additional unwind or exception
    handling libraries.
    
    This reworked version of the feature no longer modifies today's default
    unwind library for compiler-rt: which is nothing. Rather, a user
    can specify -DCLANG_DEFAULT_UNWINDLIB=libunwind when configuring
    the compiler.
    
    This should address the issues from the previous version.
    
    Update tests for new --unwindlib semantics.
    
    Differential Revision: https://reviews.llvm.org/D59109
    
    llvm-svn: 356508

diff --git clang/CMakeLists.txt clang/CMakeLists.txt
index 52b881939499..2c3fb62f6e73 100644
--- clang/CMakeLists.txt
+++ clang/CMakeLists.txt
@@ -244,6 +244,24 @@ if (NOT(CLANG_DEFAULT_RTLIB STREQUAL "" OR
     "Default runtime library to use (\"libgcc\" or \"compiler-rt\", empty for platform default)" FORCE)
 endif()
 
+set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
+  "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty to match runtime library.)")
+if (CLANG_DEFAULT_UNWINDLIB STREQUAL "")
+  if (CLANG_DEFAULT_RTLIB STREQUAL "libgcc")
+    set (CLANG_DEFAULT_UNWINDLIB "libgcc" CACHE STRING "" FORCE)
+  elseif (CLANG_DEFAULT_RTLIBS STREQUAL "libunwind")
+    set (CLANG_DEFAULT_UNWINDLIB "none" CACHE STRING "" FORCE)
+  endif()
+endif()
+
+if (NOT(CLANG_DEFAULT_UNWINDLIB STREQUAL "none" OR
+        CLANG_DEFAULT_UNWINDLIB STREQUAL "libgcc" OR
+        CLANG_DEFAULT_UNWINDLIB STREQUAL "libunwind"))
+  message(WARNING "Resetting default unwindlib to use platform default")
+  set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
+    "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty for none)" FORCE)
+endif()
+
 set(CLANG_DEFAULT_OBJCOPY "objcopy" CACHE STRING
   "Default objcopy executable to use.")
 
diff --git clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Basic/DiagnosticDriverKinds.td
index 7f75f45c6578..7e1bb33b5cef 100644
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -52,6 +52,10 @@ def err_drv_invalid_rtlib_name : Error<
   "invalid runtime library name in argument '%0'">;
 def err_drv_unsupported_rtlib_for_platform : Error<
   "unsupported runtime library '%0' for platform '%1'">;
+def err_drv_invalid_unwindlib_name : Error<
+  "invalid unwind library name in argument '%0'">;
+def err_drv_incompatible_unwindlib : Error<
+  "--rtlib=libgcc requires --unwindlib=libgcc">;
 def err_drv_invalid_stdlib_name : Error<
   "invalid library name in argument '%0'">;
 def err_drv_invalid_output_with_multiple_archs : Error<
diff --git clang/include/clang/Config/config.h.cmake clang/include/clang/Config/config.h.cmake
index 1d624450b9d9..2d4cb747e87e 100644
--- clang/include/clang/Config/config.h.cmake
+++ clang/include/clang/Config/config.h.cmake
@@ -23,6 +23,9 @@
 /* Default runtime library to use. */
 #define CLANG_DEFAULT_RTLIB "${CLANG_DEFAULT_RTLIB}"
 
+/* Default unwind library to use. */
+#define CLANG_DEFAULT_UNWINDLIB "${CLANG_DEFAULT_UNWINDLIB}"
+
 /* Default objcopy to use */
 #define CLANG_DEFAULT_OBJCOPY "${CLANG_DEFAULT_OBJCOPY}"
 
diff --git clang/include/clang/Driver/Options.td clang/include/clang/Driver/Options.td
index 601aa8744967..0e74a2d36dea 100644
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2428,6 +2428,8 @@ def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>,
   }]>;
 def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>,
   HelpText<"C++ standard library to use">, Values<"libc++,libstdc++,platform">;
+def unwindlib_EQ : Joined<["-", "--"], "unwindlib=">, Flags<[CC1Option]>,
+  HelpText<"Unwind library to use">, Values<"libgcc,unwindlib,platform">;
 def sub__library : JoinedOrSeparate<["-"], "sub_library">;
 def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">;
 def system_header_prefix : Joined<["--"], "system-header-prefix=">,
diff --git clang/include/clang/Driver/ToolChain.h clang/include/clang/Driver/ToolChain.h
index 2f9c2c190e32..d5b131bcf112 100644
--- clang/include/clang/Driver/ToolChain.h
+++ clang/include/clang/Driver/ToolChain.h
@@ -99,6 +99,12 @@ public:
     RLT_Libgcc
   };
 
+  enum UnwindLibType {
+    UNW_None,
+    UNW_CompilerRT,
+    UNW_Libgcc
+  };
+
   enum RTTIMode {
     RM_Enabled,
     RM_Disabled,
@@ -352,6 +358,10 @@ public:
     return ToolChain::CST_Libstdcxx;
   }
 
+  virtual UnwindLibType GetDefaultUnwindLibType() const {
+    return ToolChain::UNW_None;
+  }
+
   virtual std::string getCompilerRTPath() const;
 
   virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
@@ -484,6 +494,10 @@ public:
   // given compilation arguments.
   virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
 
+  // GetUnwindLibType - Determine the unwind library type to use with the
+  // given compilation arguments.
+  virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const;
+
   /// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
   /// the include paths to use for the given C++ standard library type.
   virtual void
diff --git clang/lib/Driver/ToolChain.cpp clang/lib/Driver/ToolChain.cpp
index cf3db34688df..d980dd5d23fb 100644
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -665,6 +665,33 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
   return GetDefaultRuntimeLibType();
 }
 
+ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
+    const ArgList &Args) const {
+  const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
+  StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
+
+  if (LibName == "none")
+    return ToolChain::UNW_None;
+  else if (LibName == "platform" || LibName == "") {
+    ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
+    if (RtLibType == ToolChain::RLT_CompilerRT)
+      return ToolChain::UNW_None;
+    else if (RtLibType == ToolChain::RLT_Libgcc)
+      return ToolChain::UNW_Libgcc;
+  } else if (LibName == "libunwind") {
+    if (GetRuntimeLibType(Args) == RLT_Libgcc)
+      getDriver().Diag(diag::err_drv_incompatible_unwindlib);
+    return ToolChain::UNW_CompilerRT;
+  } else if (LibName == "libgcc")
+    return ToolChain::UNW_Libgcc;
+
+  if (A)
+    getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
+        << A->getAsString(Args);
+
+  return GetDefaultUnwindLibType();
+}
+
 ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
   const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
   StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
diff --git clang/test/Driver/compiler-rt-unwind.c clang/test/Driver/compiler-rt-unwind.c
new file mode 100644
index 000000000000..00024dfa7ed3
--- /dev/null
+++ clang/test/Driver/compiler-rt-unwind.c
@@ -0,0 +1,49 @@
+// General tests that the driver handles combinations of --rtlib=XXX and
+// --unwindlib=XXX properly.
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-EMPTY %s
+// RTLIB-EMPTY: "{{.*}}lgcc"
+// RTLIB-EMPTY: "{{.*}}-lgcc_s"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-GCC %s
+// RTLIB-GCC: "{{.*}}lgcc"
+// RTLIB-GCC: "{{.*}}lgcc_s"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER-RT %s
+// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lgcc"
+// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lunwind"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1   \
+// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT %s
+// RTLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1   \
+// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
+// RUN:     --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC %s
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}libclang_rt.builtins-x86_64.a"
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}lgcc_s"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1              \
+// RUN:     --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
+// RUN:     -static --gcc-toolchain="" \
+// RUN:   | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC %s
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}libclang_rt.builtins-x86_64.a"
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}lgcc_eh"
+//
+// RUN: not %clang -no-canonical-prefixes %s -o %t.o 2> %t.err              \
+// RUN:     --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
+// RUN:     --gcc-toolchain="" \
+// RUN: FileCheck --input-file=%t.err --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER_RT %s
+// RTLIB-GCC-UNWINDLIB-COMPILER_RT: "{{[.|\\\n]*}}--rtlib=libgcc requires --unwindlib=libgcc"