mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #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
This commit is contained in:
@@ -272,6 +272,9 @@ namespace swift {
|
|||||||
/// Allow throwing call expressions without annotation with 'try'.
|
/// Allow throwing call expressions without annotation with 'try'.
|
||||||
bool EnableThrowWithoutTry = false;
|
bool EnableThrowWithoutTry = false;
|
||||||
|
|
||||||
|
/// Turn all throw sites into immediate traps.
|
||||||
|
bool ThrowsAsTraps = false;
|
||||||
|
|
||||||
/// If set, inserts instrumentation useful for testing the debugger.
|
/// If set, inserts instrumentation useful for testing the debugger.
|
||||||
bool DebuggerTestingTransform = false;
|
bool DebuggerTestingTransform = false;
|
||||||
|
|
||||||
|
|||||||
@@ -802,6 +802,9 @@ def enable_source_import : Flag<["-"], "enable-source-import">,
|
|||||||
def enable_throw_without_try : Flag<["-"], "enable-throw-without-try">,
|
def enable_throw_without_try : Flag<["-"], "enable-throw-without-try">,
|
||||||
HelpText<"Allow throwing function calls without 'try'">;
|
HelpText<"Allow throwing function calls without 'try'">;
|
||||||
|
|
||||||
|
def throws_as_traps : Flag<["-"], "throws-as-traps">,
|
||||||
|
HelpText<"Turn all throw sites into immediate traps">;
|
||||||
|
|
||||||
def import_module : Separate<["-"], "import-module">,
|
def import_module : Separate<["-"], "import-module">,
|
||||||
HelpText<"Implicitly import the specified module">;
|
HelpText<"Implicitly import the specified module">;
|
||||||
|
|
||||||
|
|||||||
@@ -723,6 +723,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
|||||||
|
|
||||||
Opts.EnableThrowWithoutTry |= Args.hasArg(OPT_enable_throw_without_try);
|
Opts.EnableThrowWithoutTry |= Args.hasArg(OPT_enable_throw_without_try);
|
||||||
|
|
||||||
|
Opts.ThrowsAsTraps |= Args.hasArg(OPT_throws_as_traps);
|
||||||
|
|
||||||
if (auto A = Args.getLastArg(OPT_enable_objc_attr_requires_foundation_module,
|
if (auto A = Args.getLastArg(OPT_enable_objc_attr_requires_foundation_module,
|
||||||
OPT_disable_objc_attr_requires_foundation_module)) {
|
OPT_disable_objc_attr_requires_foundation_module)) {
|
||||||
Opts.EnableObjCAttrRequiresFoundation
|
Opts.EnableObjCAttrRequiresFoundation
|
||||||
|
|||||||
@@ -761,6 +761,12 @@ void StmtEmitter::visitReturnStmt(ReturnStmt *S) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StmtEmitter::visitThrowStmt(ThrowStmt *S) {
|
void StmtEmitter::visitThrowStmt(ThrowStmt *S) {
|
||||||
|
if (SGF.getASTContext().LangOpts.ThrowsAsTraps) {
|
||||||
|
SGF.B.createUnconditionalFail(S, "throw turned into a trap");
|
||||||
|
SGF.B.createUnreachable(S);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ManagedValue exn = SGF.emitRValueAsSingleValue(S->getSubExpr());
|
ManagedValue exn = SGF.emitRValueAsSingleValue(S->getSubExpr());
|
||||||
SGF.emitThrow(S, exn, /* emit a call to willThrow */ true);
|
SGF.emitThrow(S, exn, /* emit a call to willThrow */ true);
|
||||||
}
|
}
|
||||||
@@ -1475,6 +1481,12 @@ void SILGenFunction::emitThrow(SILLocation loc, ManagedValue exnMV,
|
|||||||
assert(ThrowDest.isValid() &&
|
assert(ThrowDest.isValid() &&
|
||||||
"calling emitThrow with invalid throw destination!");
|
"calling emitThrow with invalid throw destination!");
|
||||||
|
|
||||||
|
if (getASTContext().LangOpts.ThrowsAsTraps) {
|
||||||
|
B.createUnconditionalFail(loc, "throw turned into a trap");
|
||||||
|
B.createUnreachable(loc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Claim the exception value. If we need to handle throwing
|
// Claim the exception value. If we need to handle throwing
|
||||||
// cleanups, the correct thing to do here is to recreate the
|
// cleanups, the correct thing to do here is to recreate the
|
||||||
// exception's cleanup when emitting each cleanup we branch through.
|
// exception's cleanup when emitting each cleanup we branch through.
|
||||||
|
|||||||
42
test/embedded/throw-trap.swift
Normal file
42
test/embedded/throw-trap.swift
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// RUN: not %target-swift-frontend -emit-ir %s -enable-experimental-feature Embedded 2>&1 | %FileCheck %s --check-prefix CHECK-EXISTENTIALS
|
||||||
|
// RUN: %target-swift-frontend -emit-sil %s -enable-experimental-feature Embedded -throws-as-traps | %FileCheck %s --check-prefix CHECK-TRAPS-SIL
|
||||||
|
// RUN: %target-swift-frontend -emit-ir %s -enable-experimental-feature Embedded -throws-as-traps | %FileCheck %s --check-prefix CHECK-TRAPS-IR
|
||||||
|
|
||||||
|
// REQUIRES: VENDOR=apple
|
||||||
|
// REQUIRES: OS=macosx
|
||||||
|
|
||||||
|
enum MyError : Error {
|
||||||
|
case a
|
||||||
|
}
|
||||||
|
|
||||||
|
public func throwing1() throws -> Int {
|
||||||
|
throw MyError.a
|
||||||
|
}
|
||||||
|
|
||||||
|
public func catching1() {
|
||||||
|
do {
|
||||||
|
try throwing1()
|
||||||
|
} catch let e as MyError {
|
||||||
|
_ = e
|
||||||
|
} catch {
|
||||||
|
_ = error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-EXISTENTIALS: error: existential can cause metadata allocation or locks
|
||||||
|
|
||||||
|
// CHECK-TRAPS-SIL: sil @$s4main9throwing1SiyKF : $@convention(thin) () -> (Int, @error any Error) {
|
||||||
|
// CHECK-TRAPS-SIL-NEXT: bb0:
|
||||||
|
// CHECK-TRAPS-SIL-NEXT: debug_value
|
||||||
|
// CHECK-TRAPS-SIL-NEXT: %1 = integer_literal $Builtin.Int1, -1
|
||||||
|
// CHECK-TRAPS-SIL-NEXT: cond_fail %1 : $Builtin.Int1, "throw turned into a trap"
|
||||||
|
// CHECK-TRAPS-SIL-NEXT: unreachable
|
||||||
|
// CHECK-TRAPS-SIL-NEXT: }
|
||||||
|
|
||||||
|
|
||||||
|
// CHECK-TRAPS-IR: define {{.*}}@"$s4main9throwing1SiyKF"{{.*}}{
|
||||||
|
// CHECK-TRAPS-IR-NEXT: entry:
|
||||||
|
// CHECK-TRAPS-IR: call void @llvm.trap()
|
||||||
|
// CHECK-TRAPS-IR-NEXT: unreachable
|
||||||
|
// CHECK-TRAPS-IR-NEXT: }
|
||||||
|
// CHECK-TRAPS-IR: define {{.*}}@"$s4main9catching1yyF"{{.*}}{
|
||||||
Reference in New Issue
Block a user