Skip to content

Commit ec87fbc

Browse files
authored
Merge pull request #70344 from kubamracek/embedded-nounwind
[embedded] Mark all functions as 'nounwind' in embedded Swift, add dependency tests
2 parents b9f7acb + fdc69fb commit ec87fbc

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

lib/IRGen/IRGenModule.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,12 @@ void IRGenModule::constructInitialFnAttributes(
14581458
Attrs.addAttribute(llvm::Attribute::StackProtectReq);
14591459
Attrs.addAttribute("stack-protector-buffer-size", llvm::utostr(8));
14601460
}
1461+
1462+
// Mark as 'nounwind' to avoid referencing exception personality symbols, this
1463+
// is okay even with C++ interop on because the landinpads are trapping.
1464+
if (Context.LangOpts.hasFeature(Feature::Embedded)) {
1465+
Attrs.addAttribute(llvm::Attribute::NoUnwind);
1466+
}
14611467
}
14621468

14631469
llvm::AttributeList IRGenModule::constructInitialAttributes() {

lib/IRGen/IRGenSIL.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,6 +1850,12 @@ IRGenSILFunction::IRGenSILFunction(IRGenModule &IGM, SILFunction *f)
18501850
CurFn->addFnAttr(llvm::Attribute::NoInline);
18511851
}
18521852

1853+
// Mark as 'nounwind' to avoid referencing exception personality symbols, this
1854+
// is okay even with C++ interop on because the landinpads are trapping.
1855+
if (IGM.Context.LangOpts.hasFeature(Feature::Embedded)) {
1856+
CurFn->addFnAttr(llvm::Attribute::NoUnwind);
1857+
}
1858+
18531859
auto optMode = f->getOptimizationMode();
18541860
if (optMode != OptimizationMode::NotSet &&
18551861
optMode != f->getModule().getOptions().OptMode) {

test/embedded/dependencies.swift

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -parse-as-library -enable-experimental-feature Embedded %s -c -o %t/a.o
3+
4+
// RUN: grep DEP\: %s | sed 's#// DEP\: ##' | sort > %t/allowed-dependencies.txt
5+
6+
// Linux/ELF doesn't use the "_" prefix in symbol mangling.
7+
// RUN: if [ %target-os == "linux-gnu" ]; then sed -E -i -e 's/^_(.*)$/\1/' %t/allowed-dependencies.txt; fi
8+
9+
// RUN: %llvm-nm --undefined-only --format=just-symbols %t/a.o | sort | tee %t/actual-dependencies.txt
10+
11+
// Fail if there is any entry in actual-dependencies.txt that's not in allowed-dependencies.txt
12+
// RUN: test -z "`comm -13 %t/allowed-dependencies.txt %t/actual-dependencies.txt`"
13+
14+
// DEP: ___stack_chk_fail
15+
// DEP: ___stack_chk_guard
16+
// DEP: _free
17+
// DEP: _memset
18+
// DEP: _putchar
19+
// DEP: _posix_memalign
20+
21+
// RUN: %target-clang -x c -c %S/Inputs/print.c -o %t/print.o
22+
// RUN: %target-clang %t/a.o %t/print.o -o %t/a.out
23+
// RUN: %target-run %t/a.out | %FileCheck %s
24+
25+
// REQUIRES: swift_in_compiler
26+
// REQUIRES: executable_test
27+
// REQUIRES: optimized_stdlib
28+
// REQUIRES: OS=macosx || OS=linux-gnu
29+
30+
@_silgen_name("putchar")
31+
func putchar(_: UInt8)
32+
33+
public func print(_ s: StaticString, terminator: StaticString = "\n") {
34+
var p = s.utf8Start
35+
while p.pointee != 0 {
36+
putchar(p.pointee)
37+
p += 1
38+
}
39+
p = terminator.utf8Start
40+
while p.pointee != 0 {
41+
putchar(p.pointee)
42+
p += 1
43+
}
44+
}
45+
46+
class MyClass {
47+
func foo() { print("MyClass.foo") }
48+
}
49+
50+
class MySubClass: MyClass {
51+
override func foo() { print("MySubClass.foo") }
52+
}
53+
54+
@main
55+
struct Main {
56+
static var objects: [MyClass] = []
57+
static func main() {
58+
print("Hello Embedded Swift!")
59+
// CHECK: Hello Embedded Swift!
60+
objects.append(MyClass())
61+
objects.append(MySubClass())
62+
for o in objects {
63+
o.foo()
64+
}
65+
// CHECK: MyClass.foo
66+
// CHECK: MySubClass.foo
67+
}
68+
}

0 commit comments

Comments
 (0)