Skip to content

Commit a559d24

Browse files
authored
Merge pull request swiftlang#68649 from kubamracek/embedded-throw-as-trap
[embedded] Add a temporary flag that turns throws into traps so that programs that use throwing can at least be compiled for now
2 parents 96ef644 + a3ee08f commit a559d24

File tree

5 files changed

+62
-0
lines changed

5 files changed

+62
-0
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ namespace swift {
272272
/// Allow throwing call expressions without annotation with 'try'.
273273
bool EnableThrowWithoutTry = false;
274274

275+
/// Turn all throw sites into immediate traps.
276+
bool ThrowsAsTraps = false;
277+
275278
/// If set, inserts instrumentation useful for testing the debugger.
276279
bool DebuggerTestingTransform = false;
277280

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,9 @@ def enable_source_import : Flag<["-"], "enable-source-import">,
802802
def enable_throw_without_try : Flag<["-"], "enable-throw-without-try">,
803803
HelpText<"Allow throwing function calls without 'try'">;
804804

805+
def throws_as_traps : Flag<["-"], "throws-as-traps">,
806+
HelpText<"Turn all throw sites into immediate traps">;
807+
805808
def import_module : Separate<["-"], "import-module">,
806809
HelpText<"Implicitly import the specified module">;
807810

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
723723

724724
Opts.EnableThrowWithoutTry |= Args.hasArg(OPT_enable_throw_without_try);
725725

726+
Opts.ThrowsAsTraps |= Args.hasArg(OPT_throws_as_traps);
727+
726728
if (auto A = Args.getLastArg(OPT_enable_objc_attr_requires_foundation_module,
727729
OPT_disable_objc_attr_requires_foundation_module)) {
728730
Opts.EnableObjCAttrRequiresFoundation

lib/SILGen/SILGenStmt.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,12 @@ void StmtEmitter::visitReturnStmt(ReturnStmt *S) {
761761
}
762762

763763
void StmtEmitter::visitThrowStmt(ThrowStmt *S) {
764+
if (SGF.getASTContext().LangOpts.ThrowsAsTraps) {
765+
SGF.B.createUnconditionalFail(S, "throw turned into a trap");
766+
SGF.B.createUnreachable(S);
767+
return;
768+
}
769+
764770
ManagedValue exn = SGF.emitRValueAsSingleValue(S->getSubExpr());
765771
SGF.emitThrow(S, exn, /* emit a call to willThrow */ true);
766772
}
@@ -1475,6 +1481,12 @@ void SILGenFunction::emitThrow(SILLocation loc, ManagedValue exnMV,
14751481
assert(ThrowDest.isValid() &&
14761482
"calling emitThrow with invalid throw destination!");
14771483

1484+
if (getASTContext().LangOpts.ThrowsAsTraps) {
1485+
B.createUnconditionalFail(loc, "throw turned into a trap");
1486+
B.createUnreachable(loc);
1487+
return;
1488+
}
1489+
14781490
// Claim the exception value. If we need to handle throwing
14791491
// cleanups, the correct thing to do here is to recreate the
14801492
// exception's cleanup when emitting each cleanup we branch through.

test/embedded/throw-trap.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: not %target-swift-frontend -emit-ir %s -enable-experimental-feature Embedded 2>&1 | %FileCheck %s --check-prefix CHECK-EXISTENTIALS
2+
// RUN: %target-swift-frontend -emit-sil %s -enable-experimental-feature Embedded -throws-as-traps | %FileCheck %s --check-prefix CHECK-TRAPS-SIL
3+
// RUN: %target-swift-frontend -emit-ir %s -enable-experimental-feature Embedded -throws-as-traps | %FileCheck %s --check-prefix CHECK-TRAPS-IR
4+
5+
// REQUIRES: VENDOR=apple
6+
// REQUIRES: OS=macosx
7+
8+
enum MyError : Error {
9+
case a
10+
}
11+
12+
public func throwing1() throws -> Int {
13+
throw MyError.a
14+
}
15+
16+
public func catching1() {
17+
do {
18+
try throwing1()
19+
} catch let e as MyError {
20+
_ = e
21+
} catch {
22+
_ = error
23+
}
24+
}
25+
26+
// CHECK-EXISTENTIALS: error: existential can cause metadata allocation or locks
27+
28+
// CHECK-TRAPS-SIL: sil @$s4main9throwing1SiyKF : $@convention(thin) () -> (Int, @error any Error) {
29+
// CHECK-TRAPS-SIL-NEXT: bb0:
30+
// CHECK-TRAPS-SIL-NEXT: debug_value
31+
// CHECK-TRAPS-SIL-NEXT: %1 = integer_literal $Builtin.Int1, -1
32+
// CHECK-TRAPS-SIL-NEXT: cond_fail %1 : $Builtin.Int1, "throw turned into a trap"
33+
// CHECK-TRAPS-SIL-NEXT: unreachable
34+
// CHECK-TRAPS-SIL-NEXT: }
35+
36+
37+
// CHECK-TRAPS-IR: define {{.*}}@"$s4main9throwing1SiyKF"{{.*}}{
38+
// CHECK-TRAPS-IR-NEXT: entry:
39+
// CHECK-TRAPS-IR: call void @llvm.trap()
40+
// CHECK-TRAPS-IR-NEXT: unreachable
41+
// CHECK-TRAPS-IR-NEXT: }
42+
// CHECK-TRAPS-IR: define {{.*}}@"$s4main9catching1yyF"{{.*}}{

0 commit comments

Comments
 (0)