Include patches

This commit is contained in:
Frederik Carlier
2024-01-15 22:03:27 +01:00
parent 1992d9c6af
commit 097b2e3ac9
7 changed files with 739 additions and 12 deletions

View File

@@ -0,0 +1,59 @@
From 10b78cc8cea65e7e77d227af4027963f39402724 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
Date: Fri, 15 Dec 2023 20:15:07 +0200
Subject: [PATCH] [llvm-windres] Pass user preprocessor arguments before the
input filename (#75389)
If passing the windres option --preprocessor, the default arguments "-E
-xc -DRC_INVOKED" aren't passed. If these are passed explicitly by the
user via --preprocessor-arg instead, we need to make sure that "-xc" is
passed before the input filename, as this compiler/preprocessor option
only has an effect on input files that follow it.
This fixes one of the issues with llvm-windres observed in
https://github.com/msys2/MINGW-packages/pull/19157.
---
llvm/test/tools/llvm-rc/preproc.test | 2 +-
llvm/test/tools/llvm-rc/windres-preproc.test | 2 +-
llvm/tools/llvm-rc/llvm-rc.cpp | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/test/tools/llvm-rc/preproc.test b/llvm/test/tools/llvm-rc/preproc.test
index f55e5434dce360b..7a6d8b3db036623 100644
--- a/llvm/test/tools/llvm-rc/preproc.test
+++ b/llvm/test/tools/llvm-rc/preproc.test
@@ -1,3 +1,3 @@
; RUN: llvm-rc -### -i%p "-DFOO1=\"foo bar\"" -UFOO2 -D FOO3 -- %p/Inputs/empty.rc | FileCheck %s
-; CHECK: {{^}} "clang" "--driver-mode=gcc" "-target" "{{.*}}-pc-windows-msvc-coff" "-E" "-xc" "-DRC_INVOKED" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc" "-I" "{{.*}}" "-D" "FOO1=\"foo bar\"" "-U" "FOO2" "-D" "FOO3"{{$}}
+; CHECK: {{^}} "clang" "--driver-mode=gcc" "-target" "{{.*}}-pc-windows-msvc-coff" "-E" "-xc" "-DRC_INVOKED" "-I" "{{.*}}" "-D" "FOO1=\"foo bar\"" "-U" "FOO2" "-D" "FOO3" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
diff --git a/llvm/test/tools/llvm-rc/windres-preproc.test b/llvm/test/tools/llvm-rc/windres-preproc.test
index e55195b3a4d2802..42e83ba13021c27 100644
--- a/llvm/test/tools/llvm-rc/windres-preproc.test
+++ b/llvm/test/tools/llvm-rc/windres-preproc.test
@@ -5,6 +5,6 @@
; RUN: llvm-windres -### --include-dir %p/incdir1 --include %p/incdir2 "-DFOO1=\\\"foo bar\\\"" -UFOO2 -D FOO3 --preprocessor-arg "-DFOO4=\\\"baz baz\\\"" -DFOO5=\"bar\" %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK1
; RUN: llvm-windres -### --include-dir %p/incdir1 --include %p/incdir2 "-DFOO1=\"foo bar\"" -UFOO2 -D FOO3 --preprocessor-arg "-DFOO4=\"baz baz\"" "-DFOO5=bar" %p/Inputs/empty.rc %t.res --use-temp-file | FileCheck %s --check-prefix=CHECK1
-; CHECK1: {{^}} "clang" "--driver-mode=gcc" "-target" "{{.*}}-{{.*}}{{mingw32|windows-gnu}}" "-E" "-xc" "-DRC_INVOKED" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc" "-I" "{{.*}}incdir1" "-I" "{{.*}}incdir2" "-D" "FOO1=\"foo bar\"" "-U" "FOO2" "-D" "FOO3" "-DFOO4=\"baz baz\"" "-D" "FOO5=bar"{{$}}
+; CHECK1: {{^}} "clang" "--driver-mode=gcc" "-target" "{{.*}}-{{.*}}{{mingw32|windows-gnu}}" "-E" "-xc" "-DRC_INVOKED" "-I" "{{.*}}incdir1" "-I" "{{.*}}incdir2" "-D" "FOO1=\"foo bar\"" "-U" "FOO2" "-D" "FOO3" "-DFOO4=\"baz baz\"" "-D" "FOO5=bar" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
; RUN: llvm-windres -### --preprocessor "i686-w64-mingw32-gcc -E -DFOO=\\\"foo\\ bar\\\"" %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK2
; CHECK2: {{^}} "i686-w64-mingw32-gcc" "-E" "-DFOO=\"foo bar\"" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp
index b955347f2a8646e..43756971fc9ba08 100644
--- a/llvm/tools/llvm-rc/llvm-rc.cpp
+++ b/llvm/tools/llvm-rc/llvm-rc.cpp
@@ -253,11 +253,11 @@ void preprocess(StringRef Src, StringRef Dst, const RcOptions &Opts,
for (const auto &S : Opts.PreprocessCmd)
Args.push_back(S);
}
+ for (const auto &S : Opts.PreprocessArgs)
+ Args.push_back(S);
Args.push_back(Src);
Args.push_back("-o");
Args.push_back(Dst);
- for (const auto &S : Opts.PreprocessArgs)
- Args.push_back(S);
if (Opts.PrintCmdAndExit || Opts.BeVerbose) {
for (const auto &A : Args) {
outs() << " ";

View File

@@ -0,0 +1,91 @@
From 1709e8c656de69f6d823a3ae6773bf815e373909 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
Date: Fri, 15 Dec 2023 20:16:19 +0200
Subject: [PATCH] [llvm-windres] Resolve the --preprocessor executable in $PATH
(#75390)
The llvm::sys::ExecuteAndWait function doesn't resolve the file to be
executed from $PATH - i.e. it is similar to execv(), not execvp().
Due to this, specifying a --preprocessor argument to llvm-windres only
worked if it specified an absolute path to the preprocessor executable.
This was observed as one of the issues in
https://github.com/msys2/MINGW-packages/pull/19157.
Before d2fa6b694c2052cef1ddd507f6569bc84e3bbe35, this usage of
--preprocessor seemed to work, because the first argument of Args[] was
ignored and llvm-windres just executed the autodetected clang executable
regardless.
Also improve the error messages printed if preprocessing failed. (If the
preprocessor executable was started but itself returned an error, we
don't get any error string.)
---
llvm/test/tools/llvm-rc/windres-preproc.test | 16 +++++++++++++++-
llvm/tools/llvm-rc/llvm-rc.cpp | 17 +++++++++++++++--
2 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/llvm/test/tools/llvm-rc/windres-preproc.test b/llvm/test/tools/llvm-rc/windres-preproc.test
index 42e83ba13021c2..74e888614aa2b9 100644
--- a/llvm/test/tools/llvm-rc/windres-preproc.test
+++ b/llvm/test/tools/llvm-rc/windres-preproc.test
@@ -7,4 +7,18 @@
; RUN: llvm-windres -### --include-dir %p/incdir1 --include %p/incdir2 "-DFOO1=\"foo bar\"" -UFOO2 -D FOO3 --preprocessor-arg "-DFOO4=\"baz baz\"" "-DFOO5=bar" %p/Inputs/empty.rc %t.res --use-temp-file | FileCheck %s --check-prefix=CHECK1
; CHECK1: {{^}} "clang" "--driver-mode=gcc" "-target" "{{.*}}-{{.*}}{{mingw32|windows-gnu}}" "-E" "-xc" "-DRC_INVOKED" "-I" "{{.*}}incdir1" "-I" "{{.*}}incdir2" "-D" "FOO1=\"foo bar\"" "-U" "FOO2" "-D" "FOO3" "-DFOO4=\"baz baz\"" "-D" "FOO5=bar" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
; RUN: llvm-windres -### --preprocessor "i686-w64-mingw32-gcc -E -DFOO=\\\"foo\\ bar\\\"" %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK2
-; CHECK2: {{^}} "i686-w64-mingw32-gcc" "-E" "-DFOO=\"foo bar\"" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
+; CHECK2: {{^}} "{{.*}}i686-w64-mingw32-gcc" "-E" "-DFOO=\"foo bar\"" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
+
+;; Test resolving the --preprocessor executable from PATH
+
+; RUN: rm -rf %t-bin/testbin
+; RUN: mkdir -p %t-bin/testbin
+; RUN: ln -s llvm-windres %t-bin/testbin/i686-w64-mingw32-gcc
+; RUN: env PATH=%t-bin/testbin llvm-windres -### --preprocessor i686-w64-mingw32-gcc --preprocessor-arg -E --preprocessor-arg -xc -DRC_INVOKED %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK3
+; CHECK3: {{^}} "{{.*}}/testbin/i686-w64-mingw32-gcc" "-E" "-xc" "-D" "RC_INVOKED" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
+
+
+;; Test error messages when unable to execute the preprocessor.
+
+; RUN: not llvm-windres --preprocessor intentionally-missing-executable %p/Inputs/empty.rc %t.res 2>&1 | FileCheck %s --check-prefix=CHECK4
+; CHECK4: llvm-rc: Preprocessing failed: Executable "intentionally-missing-executable" doesn't exist!
diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp
index 43756971fc9ba0..27fb0309e0ee54 100644
--- a/llvm/tools/llvm-rc/llvm-rc.cpp
+++ b/llvm/tools/llvm-rc/llvm-rc.cpp
@@ -248,10 +248,17 @@ void preprocess(StringRef Src, StringRef Dst, const RcOptions &Opts,
SmallVector<StringRef, 8> Args = {
Clang, "--driver-mode=gcc", "-target", Opts.Triple, "-E",
"-xc", "-DRC_INVOKED"};
+ std::string PreprocessorExecutable;
if (!Opts.PreprocessCmd.empty()) {
Args.clear();
for (const auto &S : Opts.PreprocessCmd)
Args.push_back(S);
+ if (!sys::fs::can_execute(Args[0])) {
+ if (auto P = sys::findProgramByName(Args[0])) {
+ PreprocessorExecutable = *P;
+ Args[0] = PreprocessorExecutable;
+ }
+ }
}
for (const auto &S : Opts.PreprocessArgs)
Args.push_back(S);
@@ -269,9 +276,15 @@ void preprocess(StringRef Src, StringRef Dst, const RcOptions &Opts,
}
// The llvm Support classes don't handle reading from stdout of a child
// process; otherwise we could avoid using a temp file.
- int Res = sys::ExecuteAndWait(Args[0], Args);
+ std::string ErrMsg;
+ int Res =
+ sys::ExecuteAndWait(Args[0], Args, /*Env=*/std::nullopt, /*Redirects=*/{},
+ /*SecondsToWait=*/0, /*MemoryLimit=*/0, &ErrMsg);
if (Res) {
- fatalError("llvm-rc: Preprocessing failed.");
+ if (!ErrMsg.empty())
+ fatalError("llvm-rc: Preprocessing failed: " + ErrMsg);
+ else
+ fatalError("llvm-rc: Preprocessing failed.");
}
}

View File

@@ -0,0 +1,254 @@
From 1d5106d69cf475215887c42834158d710e586f1b Mon Sep 17 00:00:00 2001
From: Frederik Carlier <frederik.carlier@keysight.com>
Date: Wed, 10 Jan 2024 08:52:13 -0800
Subject: [PATCH] Objective C: use C++ exceptions on MinGW+GNUstep (#77255)
The GNUstep Objective C runtime (libobjc2) is adding support for the GNU
ABI on Windows (more specifically, MinGW). The libobjc2 runtime uses C++
exceptions in that configuration; this PR updates clang to act
accordingly.
The corresponding change to libobjc2 is here:
https://github.com/gnustep/libobjc2/pull/267
---
clang/lib/CodeGen/CGException.cpp | 7 ++-
clang/lib/CodeGen/CGObjCGNU.cpp | 35 +++++++-----
.../test/CodeGenObjC/exceptions-personality.m | 53 +++++++++++++++++++
clang/test/CodeGenObjC/personality.m | 5 +-
clang/test/CodeGenObjCXX/personality.mm | 5 +-
5 files changed, 87 insertions(+), 18 deletions(-)
create mode 100644 clang/test/CodeGenObjC/exceptions-personality.m
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 0d507da5c1ba92f..56a246eb65e0a82 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -156,7 +156,9 @@ static const EHPersonality &getObjCPersonality(const TargetInfo &Target,
case ObjCRuntime::WatchOS:
return EHPersonality::NeXT_ObjC;
case ObjCRuntime::GNUstep:
- if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7))
+ if (T.isOSCygMing())
+ return EHPersonality::GNU_CPlusPlus_SEH;
+ else if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7))
return EHPersonality::GNUstep_ObjC;
[[fallthrough]];
case ObjCRuntime::GCC:
@@ -210,7 +212,8 @@ static const EHPersonality &getObjCXXPersonality(const TargetInfo &Target,
return getObjCPersonality(Target, L);
case ObjCRuntime::GNUstep:
- return EHPersonality::GNU_ObjCXX;
+ return Target.getTriple().isOSCygMing() ? EHPersonality::GNU_CPlusPlus_SEH
+ : EHPersonality::GNU_ObjCXX;
// The GCC runtime's personality function inherently doesn't support
// mixed EH. Use the ObjC personality just to avoid returning null.
diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index 9443fecf9b79469..cd1a0b6a130ff01 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -168,6 +168,8 @@ class CGObjCGNU : public CGObjCRuntime {
/// Does the current target use SEH-based exceptions? False implies
/// Itanium-style DWARF unwinding.
bool usesSEHExceptions;
+ /// Does the current target uses C++-based exceptions?
+ bool usesCxxExceptions;
/// Helper to check if we are targeting a specific runtime version or later.
bool isRuntime(ObjCRuntime::Kind kind, unsigned major, unsigned minor=0) {
@@ -819,12 +821,18 @@ class CGObjCGNUstep : public CGObjCGNU {
SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy,
PtrToObjCSuperTy, SelectorTy);
// If we're in ObjC++ mode, then we want to make
- if (usesSEHExceptions) {
- llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
- // void objc_exception_rethrow(void)
- ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy);
+ llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
+ if (usesCxxExceptions) {
+ // void *__cxa_begin_catch(void *e)
+ EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy);
+ // void __cxa_end_catch(void)
+ ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy);
+ // void objc_exception_rethrow(void*)
+ ExceptionReThrowFn.init(&CGM, "__cxa_rethrow", PtrTy);
+ } else if (usesSEHExceptions) {
+ // void objc_exception_rethrow(void)
+ ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy);
} else if (CGM.getLangOpts().CPlusPlus) {
- llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
// void *__cxa_begin_catch(void *e)
EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy);
// void __cxa_end_catch(void)
@@ -833,7 +841,6 @@ class CGObjCGNUstep : public CGObjCGNU {
ExceptionReThrowFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy,
PtrTy);
} else if (R.getVersion() >= VersionTuple(1, 7)) {
- llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
// id objc_begin_catch(void *e)
EnterCatchFn.init(&CGM, "objc_begin_catch", IdTy, PtrTy);
// void objc_end_catch(void)
@@ -841,7 +848,6 @@ class CGObjCGNUstep : public CGObjCGNU {
// void _Unwind_Resume_or_Rethrow(void*)
ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy, PtrTy);
}
- llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
SetPropertyAtomic.init(&CGM, "objc_setProperty_atomic", VoidTy, IdTy,
SelectorTy, IdTy, PtrDiffTy);
SetPropertyAtomicCopy.init(&CGM, "objc_setProperty_atomic_copy", VoidTy,
@@ -2126,6 +2132,9 @@ CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
usesSEHExceptions =
cgm.getContext().getTargetInfo().getTriple().isWindowsMSVCEnvironment();
+ usesCxxExceptions =
+ cgm.getContext().getTargetInfo().getTriple().isOSCygMing() &&
+ isRuntime(ObjCRuntime::GNUstep, 2);
CodeGenTypes &Types = CGM.getTypes();
IntTy = cast<llvm::IntegerType>(
@@ -2212,7 +2221,10 @@ CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
// void objc_exception_throw(id);
ExceptionThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy);
- ExceptionReThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy);
+ ExceptionReThrowFn.init(&CGM,
+ usesCxxExceptions ? "objc_exception_rethrow"
+ : "objc_exception_throw",
+ VoidTy, IdTy);
// int objc_sync_enter(id);
SyncEnterFn.init(&CGM, "objc_sync_enter", IntTy, IdTy);
// int objc_sync_exit(id);
@@ -2389,7 +2401,7 @@ llvm::Constant *CGObjCGNUstep::GetEHType(QualType T) {
if (usesSEHExceptions)
return CGM.getCXXABI().getAddrOfRTTIDescriptor(T);
- if (!CGM.getLangOpts().CPlusPlus)
+ if (!CGM.getLangOpts().CPlusPlus && !usesCxxExceptions)
return CGObjCGNU::GetEHType(T);
// For Objective-C++, we want to provide the ability to catch both C++ and
@@ -3995,7 +4007,7 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF,
ExceptionAsObject = CGF.ObjCEHValueStack.back();
isRethrow = true;
}
- if (isRethrow && usesSEHExceptions) {
+ if (isRethrow && (usesSEHExceptions || usesCxxExceptions)) {
// For SEH, ExceptionAsObject may be undef, because the catch handler is
// not passed it for catchalls and so it is not visible to the catch
// funclet. The real thrown object will still be live on the stack at this
@@ -4005,8 +4017,7 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF,
// argument.
llvm::CallBase *Throw = CGF.EmitRuntimeCallOrInvoke(ExceptionReThrowFn);
Throw->setDoesNotReturn();
- }
- else {
+ } else {
ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy);
llvm::CallBase *Throw =
CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject);
diff --git a/clang/test/CodeGenObjC/exceptions-personality.m b/clang/test/CodeGenObjC/exceptions-personality.m
new file mode 100644
index 000000000000000..9c25ee38b6d7cf5
--- /dev/null
+++ b/clang/test/CodeGenObjC/exceptions-personality.m
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-w64-windows-gnu -emit-llvm -fobjc-runtime=gnustep-2.0 -fexceptions -fobjc-exceptions -o %t %s
+// RUN: FileCheck --check-prefixes=CHECK-MINGW-OBJC2 < %t %s
+
+// RUN: %clang_cc1 -triple x86_64-w64-windows-gnu -emit-llvm -fobjc-runtime=gcc -fexceptions -fobjc-exceptions -o %t %s
+// RUN: FileCheck --check-prefixes=CHECK-MINGW-GCC < %t %s
+
+// RUN: %clang_cc1 -triple x86_64-w64-windows-msvc -emit-llvm -fobjc-runtime=gnustep-2.0 -fexceptions -fobjc-exceptions -o %t %s
+// RUN: FileCheck --check-prefixes=CHECK-MSVC-OBJC2 < %t %s
+
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -fobjc-runtime=gnustep-2.0 -fexceptions -fobjc-exceptions -o %t %s
+// RUN: FileCheck --check-prefixes=CHECK-LINUX-OBJC2 < %t %s
+
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -fobjc-runtime=gcc -fexceptions -fobjc-exceptions -o %t %s
+// RUN: FileCheck --check-prefixes=CHECK-LINUX-GCC < %t %s
+@interface Foo @end
+
+void throwing(void) {
+ @try
+ {
+ // CHECK-MINGW-OBJC2: personality ptr @__gxx_personality_seh0
+ // CHECK-MINGW-OBJC2: invoke void @objc_exception_throw
+
+ // CHECK-MINGW-GCC: personality ptr @__gnu_objc_personality_v0
+ // CHECK-MINGW-GCC: invoke void @objc_exception_throw
+
+ // CHECK-MSVC-OBJC2: personality ptr @__CxxFrameHandler3
+ // CHECK-MSVC-OBJC2: invoke void @objc_exception_throw
+
+ // CHECK-LINUX-OBJC2: personality ptr @__gnustep_objc_personality_v0
+ // CHECK-LINUX-OBJC2: invoke void @objc_exception_throw
+
+ // CHECK-LINUX-GCC: personality ptr @__gnu_objc_personality_v0
+ @throw(@"error!");
+ }
+ @catch(...)
+ {
+ // CHECK-MINGW-OBJC2: call ptr @__cxa_begin_catch
+ // CHECK-MINGW-OBJC2: invoke ptr @__cxa_rethrow
+ // CHECK-MINGW-OBJC2: invoke void @__cxa_end_catch
+
+ // CHECK-MINGW-GCC: call void @objc_exception_throw
+
+ // CHECK-MSVC-OBJC2: call void @objc_exception_rethrow
+
+ // CHECK-LINUX-OBJC2: call ptr @objc_begin_catch
+ // CHECK-LINUX-OBJC2: invoke void @objc_exception_throw
+ // CHECK-LINUX-OBJC2: invoke void @objc_end_catch()
+
+ // CHECK-LINUX-GCC: invoke void @objc_exception_throw
+
+ @throw;
+ }
+}
diff --git a/clang/test/CodeGenObjC/personality.m b/clang/test/CodeGenObjC/personality.m
index 6ec67ace3f1ac31..ede0aa34eaf6256 100644
--- a/clang/test/CodeGenObjC/personality.m
+++ b/clang/test/CodeGenObjC/personality.m
@@ -27,8 +27,8 @@
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fobjc-runtime=ios -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-NS
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fobjc-runtime=macosx -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-NS
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fobjc-runtime=watchos -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-NS
-// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fobjc-runtime=gnustep-1.7 -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNUSTEP-1_7
-// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fobjc-runtime=gnustep -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNUSTEP
+// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fobjc-runtime=gnustep-1.7 -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-WIN-GNU
+// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fobjc-runtime=gnustep -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-WIN-GNU
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fobjc-runtime=gcc -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GCC
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -exception-model=seh -fobjc-exceptions -fobjc-runtime=gcc -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GCC-SEH
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -exception-model=sjlj -fobjc-exceptions -fobjc-runtime=gcc -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GCC-SJLJ
@@ -50,6 +50,7 @@
// CHECK-OBJFW-SJLJ: personality ptr @__gnu_objc_personality_sj0
// CHECK-WIN-MSVC: personality ptr @__CxxFrameHandler3
+// CHECK-WIN-GNU: personality ptr @__gxx_personality_seh0
// CHECK-MACOSX-FRAGILE-MINGW-DWARF: personality ptr @__gcc_personality_v0
// CHECK-MACOSX-FRAGILE-MINGW-SEH: personality ptr @__gcc_personality_seh0
diff --git a/clang/test/CodeGenObjCXX/personality.mm b/clang/test/CodeGenObjCXX/personality.mm
index c6debe6f60c2a25..b8c7af962bd0bd6 100644
--- a/clang/test/CodeGenObjCXX/personality.mm
+++ b/clang/test/CodeGenObjCXX/personality.mm
@@ -50,8 +50,8 @@
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -exception-model=dwarf -fobjc-exceptions -fcxx-exceptions -fobjc-runtime=watchos -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-NS
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -exception-model=seh -fobjc-exceptions -fcxx-exceptions -fobjc-runtime=watchos -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-NS
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -exception-model=sjlj -fobjc-exceptions -fcxx-exceptions -fobjc-runtime=watchos -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-NS
-// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-runtime=gnustep-1.7 -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNUSTEP-1_7
-// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-runtime=gnustep -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GNUSTEP
+// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-runtime=gnustep-1.7 -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-WIN-GNU
+// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-runtime=gnustep -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-WIN-GNU
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-runtime=gcc -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GCC
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -exception-model=dwarf -fobjc-exceptions -fcxx-exceptions -fobjc-runtime=gcc -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GCC
// RUN: %clang_cc1 -triple i686-unknown-windows-gnu -fexceptions -exception-model=seh -fobjc-exceptions -fcxx-exceptions -fobjc-runtime=gcc -S -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-GCC-SEH
@@ -81,6 +81,7 @@ + (void)e:(id)xception;
// CHECK-OBJFW-SJLJ: personality ptr @__gnu_objc_personality_sj0
// CHECK-WIN-MSVC: personality ptr @__CxxFrameHandler3
+// CHECK-WIN-GNU: personality ptr @__gxx_personality_seh0
void f(void) {
@try {

View File

@@ -0,0 +1,148 @@
From 9e3d915d8ebf86e24c9ff58766be8e7c6aa7b0c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
Date: Mon, 18 Dec 2023 12:31:05 +0200
Subject: [PATCH] [llvm-windres] Change the interpretation of --preprocessor to
match Binutils 2.36 (#75391)
Binutils 2.36 had a somewhat controversial change in how the
--preprocessor option was handled in GNU windres; previously, the option
was interpreted as a part of the command string, potentially containing
multiple arguments (which even was hinted at in the documentation).
In Binutils 2.36, this was changed to interpret the --preprocessor
argument as one argument (possibly containing spaces) pointing at the
preprocessor executable.
The existing behaviour where implicit arguments like -E -xc -DRC_INVOKED
are dropped if --preprocessor is specified, was kept.
This was a breaking change for some users of GNU windres, see
https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=21c33bcbe36377abf01614fb1b9be439a3b6de20,
https://sourceware.org/bugzilla/show_bug.cgi?id=27594, and
https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=5edb8e3f5ad8d74a83fc0df7f6e4514eed0aa77f.
As multiple years have passed since, the behaviour change seems to be
here to stay, and any users of the previous form of the option have been
forced to avoid this construct. Thus update llvm-windres to match the
new way Binutils of handling this option.
One construct for specifying the path to the preprocessor, which works
both before and after binutils 2.36 (and this change in llvm-windres) is
to specify options like this:
--preprocessor path/to/executable --preprocessor-arg -E
--preprocessor-arg -xc -DRC_INVOKED
---
llvm/test/tools/llvm-rc/windres-preproc.test | 9 +++-
llvm/tools/llvm-rc/llvm-rc.cpp | 44 +++-----------------
2 files changed, 12 insertions(+), 41 deletions(-)
diff --git a/llvm/test/tools/llvm-rc/windres-preproc.test b/llvm/test/tools/llvm-rc/windres-preproc.test
index 74e888614aa2b9..13f82299a074bb 100644
--- a/llvm/test/tools/llvm-rc/windres-preproc.test
+++ b/llvm/test/tools/llvm-rc/windres-preproc.test
@@ -6,8 +6,8 @@
; RUN: llvm-windres -### --include-dir %p/incdir1 --include %p/incdir2 "-DFOO1=\\\"foo bar\\\"" -UFOO2 -D FOO3 --preprocessor-arg "-DFOO4=\\\"baz baz\\\"" -DFOO5=\"bar\" %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK1
; RUN: llvm-windres -### --include-dir %p/incdir1 --include %p/incdir2 "-DFOO1=\"foo bar\"" -UFOO2 -D FOO3 --preprocessor-arg "-DFOO4=\"baz baz\"" "-DFOO5=bar" %p/Inputs/empty.rc %t.res --use-temp-file | FileCheck %s --check-prefix=CHECK1
; CHECK1: {{^}} "clang" "--driver-mode=gcc" "-target" "{{.*}}-{{.*}}{{mingw32|windows-gnu}}" "-E" "-xc" "-DRC_INVOKED" "-I" "{{.*}}incdir1" "-I" "{{.*}}incdir2" "-D" "FOO1=\"foo bar\"" "-U" "FOO2" "-D" "FOO3" "-DFOO4=\"baz baz\"" "-D" "FOO5=bar" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
-; RUN: llvm-windres -### --preprocessor "i686-w64-mingw32-gcc -E -DFOO=\\\"foo\\ bar\\\"" %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK2
-; CHECK2: {{^}} "{{.*}}i686-w64-mingw32-gcc" "-E" "-DFOO=\"foo bar\"" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
+; RUN: llvm-windres -### --preprocessor "i686-w64-mingw32-gcc" --preprocessor-arg -E "-DFOO=\\\"foo bar\\\"" %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK2
+; CHECK2: {{^}} "{{.*}}i686-w64-mingw32-gcc" "-E" "-D" "FOO=\"foo bar\"" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
;; Test resolving the --preprocessor executable from PATH
@@ -22,3 +22,8 @@
; RUN: not llvm-windres --preprocessor intentionally-missing-executable %p/Inputs/empty.rc %t.res 2>&1 | FileCheck %s --check-prefix=CHECK4
; CHECK4: llvm-rc: Preprocessing failed: Executable "intentionally-missing-executable" doesn't exist!
+
+;; Test --preprocessor with an argument with spaces.
+
+; RUN: llvm-windres -### --preprocessor "path with spaces/gcc" %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK5
+; CHECK5: {{^}} "path with spaces/gcc" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}}
diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp
index 27fb0309e0ee54..78ab96492acc75 100644
--- a/llvm/tools/llvm-rc/llvm-rc.cpp
+++ b/llvm/tools/llvm-rc/llvm-rc.cpp
@@ -209,7 +209,7 @@ struct RcOptions {
bool Preprocess = true;
bool PrintCmdAndExit = false;
std::string Triple;
- std::vector<std::string> PreprocessCmd;
+ std::optional<std::string> Preprocessor;
std::vector<std::string> PreprocessArgs;
std::string InputFile;
@@ -229,7 +229,7 @@ struct RcOptions {
void preprocess(StringRef Src, StringRef Dst, const RcOptions &Opts,
const char *Argv0) {
std::string Clang;
- if (Opts.PrintCmdAndExit || !Opts.PreprocessCmd.empty()) {
+ if (Opts.PrintCmdAndExit || Opts.Preprocessor) {
Clang = "clang";
} else {
ErrorOr<std::string> ClangOrErr = findClang(Argv0, Opts.Triple);
@@ -249,10 +249,9 @@ void preprocess(StringRef Src, StringRef Dst, const RcOptions &Opts,
Clang, "--driver-mode=gcc", "-target", Opts.Triple, "-E",
"-xc", "-DRC_INVOKED"};
std::string PreprocessorExecutable;
- if (!Opts.PreprocessCmd.empty()) {
+ if (Opts.Preprocessor) {
Args.clear();
- for (const auto &S : Opts.PreprocessCmd)
- Args.push_back(S);
+ Args.push_back(*Opts.Preprocessor);
if (!sys::fs::can_execute(Args[0])) {
if (auto P = sys::findProgramByName(Args[0])) {
PreprocessorExecutable = *P;
@@ -342,36 +341,6 @@ std::string unescape(StringRef S) {
return Out;
}
-std::vector<std::string> unescapeSplit(StringRef S) {
- std::vector<std::string> OutArgs;
- std::string Out;
- bool InQuote = false;
- for (int I = 0, E = S.size(); I < E; I++) {
- if (S[I] == '\\') {
- if (I + 1 < E)
- Out.push_back(S[++I]);
- else
- fatalError("Unterminated escape");
- continue;
- }
- if (S[I] == '"') {
- InQuote = !InQuote;
- continue;
- }
- if (S[I] == ' ' && !InQuote) {
- OutArgs.push_back(Out);
- Out.clear();
- continue;
- }
- Out.push_back(S[I]);
- }
- if (InQuote)
- fatalError("Unterminated quote");
- if (!Out.empty())
- OutArgs.push_back(Out);
- return OutArgs;
-}
-
RcOptions parseWindresOptions(ArrayRef<const char *> ArgsArr,
ArrayRef<const char *> InputArgsArray,
std::string Prefix) {
@@ -506,11 +475,8 @@ RcOptions parseWindresOptions(ArrayRef<const char *> ArgsArr,
break;
}
}
- // TODO: If --use-temp-file is set, we shouldn't be unescaping
- // the --preprocessor argument either, only splitting it.
if (InputArgs.hasArg(WINDRES_preprocessor))
- Opts.PreprocessCmd =
- unescapeSplit(InputArgs.getLastArgValue(WINDRES_preprocessor));
+ Opts.Preprocessor = InputArgs.getLastArgValue(WINDRES_preprocessor);
Opts.Params.CodePage = CpWin1252; // Different default
if (InputArgs.hasArg(WINDRES_codepage)) {

View File

@@ -7,8 +7,6 @@
# Contributor: Oscar Fuentes <ofv@wanadoo.es>
# Contributor: Adrian Pop <adrian.pop@liu.se>
objc_type_encoding_commit_id="c65ae76326040369bcd3a85678ab76e402140036"
if [[ $MINGW_PACKAGE_PREFIX == *-clang-* ]]; then
_clangprefix=1
_compiler=clang
@@ -73,14 +71,14 @@ source=("${_url}/llvm-${pkgver}.src.tar.xz"{,.sig}
"0102-Rename-flang-new-flang-experimental-exec-to-flang.patch"
"0303-ignore-new-bfd-options.patch"
# Objective C: Use C++ mode unconditionally on MinGW
https://github.com/qmfrederik/llvm-project/commit/1d5106d69cf475215887c42834158d710e586f1b.patch
"1d5106d69cf475215887c42834158d710e586f1b.patch"
# Objective C: Mark instance variable offsets with DllExport/DllImport when targetting COFF
https://github.com/llvm/llvm-project/commit/b81ba52e15d95c3353489d4ce2f61c3771714c28.patch
"b81ba52e15d95c3353489d4ce2f61c3771714c28.patch"
# Objective C: Work around type encodings which include '=' causing lld to fail
https://github.com/llvm/llvm-project/commit/${objc_type_encoding_commit_id}.patch
https://github.com/llvm/llvm-project/commit/10b78cc8cea65e7e77d227af4027963f39402724.patch
https://github.com/llvm/llvm-project/commit/1709e8c656de69f6d823a3ae6773bf815e373909.patch
https://github.com/llvm/llvm-project/commit/9e3d915d8ebf86e24c9ff58766be8e7c6aa7b0c0.patch)
"c65ae76326040369bcd3a85678ab76e402140036.patch"
"10b78cc8cea65e7e77d227af4027963f39402724.patch"
"1709e8c656de69f6d823a3ae6773bf815e373909.patch"
"9e3d915d8ebf86e24c9ff58766be8e7c6aa7b0c0.patch")
# Some patch notes :)
#0001-0099 -> llvm
#0101-0199 -> clang
@@ -108,10 +106,10 @@ sha256sums=('b638167da139126ca11917b6880207cc6e8f9d1cbb1a48d87d017f697ef78188'
'715cb8862753854b2d9256e0b70003e2d1f57083d83eaeaf5a095fc72b8a4e26'
'2770cadf8ccf6b31aece6aee8f76dceb71e6e9d01fdf3be74c3743480ce34899'
'de631ab199a6fe83b3f695350bffaad067a2f95fc2ba9c8fe57dc85665d3653c'
'b6095ce7fa2d0afa4135d6fc4375d4ca4b9f39ac27378d05ea76cf6dfd6676f1'
'65b50e18793686ec6620896155797ad2cc93d00f8a458c735a524a8c73d67980'
'b23427a58ddf2f8fd16605ab9cc89d1233a409ee0a208f6d8d1a34204f716426'
'SKIP'
'88c4994341b4de2a23929e31a98031cb94b6d42575f9d8fd6e120f61ae0c5747'
'a92baac68b7e7deb81edf197fee4e2ffb03a71488a05e7145bdd12f51d443d5a'
'b7f484b02c79dfaac81243b085dd4196a7f46226ac64e0ba1690c41391a4a157'
'0f3dcb8b2d5f90f8ff2e77896d3b0ef6c87af8214e679917898e35dd678daef5'
'e745aa71c903445c86639507256a5ca775e69b569b58f2ff48d6047703cfc81a')
validpgpkeys=('B6C8F98282B944E3B0D5C2530FC3042E345AD05D' # Hans Wennborg, Google.
@@ -156,7 +154,7 @@ prepare() {
apply_patch_with_msg \
"1d5106d69cf475215887c42834158d710e586f1b.patch" \
"b81ba52e15d95c3353489d4ce2f61c3771714c28.patch" \
"${objc_type_encoding_commit_id}.patch"
"c65ae76326040369bcd3a85678ab76e402140036.patch"
# Patch llvm
cd "${srcdir}/llvm"

View File

@@ -0,0 +1,136 @@
From b81ba52e15d95c3353489d4ce2f61c3771714c28 Mon Sep 17 00:00:00 2001
From: Frederik Carlier <frederik.carlier@quamotion.mobi>
Date: Tue, 9 Jan 2024 10:15:01 +0100
Subject: [PATCH] Set dllstorage on ObjectiveC ivar offsets (#77385)
Mark instance variable offset symbols with `dllexport`/`dllimport` if
they are not hidden and the interface declaration is marked with
`dllexport`/`dllimport`, when using the GNUstep 2.x ABI.
/cc @davidchisnall
---
clang/lib/CodeGen/CGObjCGNU.cpp | 2 ++
clang/test/CodeGenObjC/dllstorage.m | 29 +++++++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index 4ca1a8cce64d89..9443fecf9b7946 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -1851,6 +1851,8 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
llvm::GlobalValue::HiddenVisibility :
llvm::GlobalValue::DefaultVisibility;
OffsetVar->setVisibility(ivarVisibility);
+ if (ivarVisibility != llvm::GlobalValue::HiddenVisibility)
+ CGM.setGVProperties(OffsetVar, OID->getClassInterface());
ivarBuilder.add(OffsetVar);
// Ivar size
ivarBuilder.addInt(Int32Ty,
diff --git a/clang/test/CodeGenObjC/dllstorage.m b/clang/test/CodeGenObjC/dllstorage.m
index 64ba21f9769ae2..0dbf1881caa9c0 100644
--- a/clang/test/CodeGenObjC/dllstorage.m
+++ b/clang/test/CodeGenObjC/dllstorage.m
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fdeclspec -fobjc-runtime=ios -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap -check-prefix CHECK-IR %s
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fdeclspec -fobjc-runtime=gnustep-2.0 -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap -check-prefix CHECK-NF %s
// RUN: %clang_cc1 -triple i686-windows-itanium -fms-extensions -fobjc-runtime=macosx -fdeclspec -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap -check-prefix CHECK-IR %s
// RUN: %clang_cc1 -triple i686-windows-itanium -fms-extensions -fobjc-runtime=objfw -fdeclspec -fobjc-exceptions -S -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap -check-prefix CHECK-FW %s
@@ -12,6 +13,8 @@ + (instancetype) new;
// CHECK-IR-DAG: @"OBJC_METACLASS_$_I" = external dllimport global %struct._class_t
// CHECK-IR-DAG: @"OBJC_CLASS_$_I" = external dllimport global %struct._class_t
+// CHECK-NF-DAG: @"$_OBJC_CLASS_I" = external dllimport global ptr
+
__declspec(dllexport)
@interface J : I
@end
@@ -22,6 +25,9 @@ @interface J : I
// CHECK-FW-DAG: @_OBJC_METACLASS_J = dso_local dllexport global
// CHECK-FW-DAG: @_OBJC_CLASS_J = dso_local dllexport global
+// CHECK-NF-DAG: @"$_OBJC_METACLASS_J" = internal global
+// CHECK-NF-DAG: @"$_OBJC_CLASS_J" = dllexport global
+
@implementation J {
id _ivar;
}
@@ -29,6 +35,8 @@ @implementation J {
// CHECK-IR-DAG: @"OBJC_IVAR_$_J._ivar" = global i32
+// CHECK-NF-DAG: @"__objc_ivar_offset_J._ivar.\01" = hidden global i32
+
@interface K : J
@end
@@ -38,6 +46,9 @@ @interface K : J
// CHECK-FW-DAG: @_OBJC_METACLASS_K = dso_local global
// CHECK-FW-DAG: @_OBJC_CLASS_K = dso_local global
+// CHECK-NF-DAG: @"$_OBJC_METACLASS_K" = internal global
+// CHECK-NF-DAG: @"$_OBJC_CLASS_K" = global
+
@implementation K {
id _ivar;
}
@@ -45,6 +56,8 @@ @implementation K {
// CHECK-IR-DAG: @"OBJC_IVAR_$_K._ivar" = global i32
+// CHECK-NF-DAG: @"__objc_ivar_offset_K._ivar.\01" = hidden global i32
+
__declspec(dllexport)
@interface L : K
@end
@@ -55,6 +68,9 @@ @interface L : K
// CHECK-FW-DAG: @_OBJC_METACLASS_L = dso_local dllexport global
// CHECK-FW-DAG: @_OBJC_CLASS_L = dso_local dllexport global
+// CHECK-NF-DAG: @"$_OBJC_METACLASS_L" = internal global
+// CHECK-NF-DAG: @"$_OBJC_CLASS_L" = dllexport global
+
@implementation L {
id _none;
@@ -78,6 +94,12 @@ @implementation L {
// CHECK-IR-DAG: @"OBJC_IVAR_$_L._package" = global i32
// CHECK-IR-DAG: @"OBJC_IVAR_$_L._private" = global i32
+// CHECK-NF-DAG: @"__objc_ivar_offset_L._none.\01" = hidden global i32
+// CHECK-NF-DAG: @"__objc_ivar_offset_L._public.\01" = dso_local dllexport global i32
+// CHECK-NF-DAG: @"__objc_ivar_offset_L._protected.\01" = dso_local dllexport global i32
+// CHECK-NF-DAG: @"__objc_ivar_offset_L._package.\01" = hidden global i32
+// CHECK-NF-DAG: @"__objc_ivar_offset_L._private.\01" = hidden global i32
+
__declspec(dllimport)
@interface M : I {
@public
@@ -89,6 +111,9 @@ @interface M : I {
// CHECK-IR-DAG: @"OBJC_IVAR_$_M._ivar" = external dllimport global i32
+// CHECK-NF-DAG: @"$_OBJC_REF_CLASS_M" = external dllimport global ptr
+// CHECK-NF-DAG: @"__objc_ivar_offset_M._ivar.\01" = external global i32
+
__declspec(dllexport)
__attribute__((__objc_exception__))
@interface N : I
@@ -97,6 +122,8 @@ @interface N : I
// CHECK-FW-DAG: @_OBJC_METACLASS_N = dso_local dllexport global
// CHECK-FW-DAG: @_OBJC_CLASS_N = dso_local dllexport global
+// CHECK-NF-DAG: @"$_OBJC_CLASS_N" = dllexport global
+
@implementation N : I
@end
@@ -124,6 +151,8 @@ id f(Q *q) {
// CHECK-IR-DAG: @"OBJC_IVAR_$_M._ivar" = external dllimport global i32
+// CHECK-NF-DAG: @"__objc_ivar_offset_M._ivar.\01" = external global i32
+
int g(void) {
@autoreleasepool {
M *mi = [M new];

View File

@@ -0,0 +1,41 @@
From c65ae76326040369bcd3a85678ab76e402140036 Mon Sep 17 00:00:00 2001
From: Frederik Carlier <frederik.carlier@keysight.com>
Date: Wed, 10 Jan 2024 16:51:18 +0000
Subject: [PATCH] Objective C: Avoid including '=' characters in type encodings
in instance variable names
---
clang/lib/CodeGen/CGObjCGNU.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index cd1a0b6a130ff01..62da81e59f34de5 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -1437,6 +1437,8 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
std::string MangledTypes = std::string(TypeEncoding);
std::replace(MangledTypes.begin(), MangledTypes.end(),
'@', '\1');
+ std::replace(MangledTypes.begin(), MangledTypes.end(),
+ '=', '\2');
std::string TypesVarName = ".objc_sel_types_" + MangledTypes;
auto *TypesGlobal = TheModule.getGlobalVariable(TypesVarName);
if (!TypesGlobal) {
@@ -1460,6 +1462,8 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
std::string MangledTypes = TypeEncoding;
std::replace(MangledTypes.begin(), MangledTypes.end(),
'@', '\1');
+ std::replace(MangledTypes.begin(), MangledTypes.end(),
+ '=', '\2');
auto SelVarName = (StringRef(".objc_selector_") + Sel.getAsString() + "_" +
MangledTypes).str();
if (auto *GV = TheModule.getNamedGlobal(SelVarName))
@@ -1674,6 +1678,8 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
// Prevent the @ from being interpreted as a symbol version.
std::replace(TypeEncoding.begin(), TypeEncoding.end(),
'@', '\1');
+ std::replace(TypeEncoding.begin(), TypeEncoding.end(),
+ '=', '\2');
const std::string Name = "__objc_ivar_offset_" + ID->getNameAsString()
+ '.' + Ivar->getNameAsString() + '.' + TypeEncoding;
return Name;