Skip to content

Commit d2e1bcd

Browse files
committed
[silgen] When transforming values into an existential box representation, do it at +1.
In general, SILGen assumes that only +1 values are "forwarded" into memory. This is because we want any value that is stored in memory to not be dependent on other values and for the forwarded object to be able to maintain its own liveness. So this assert was correct to fire. The specific test case that exposed this issue is: What happened here is that we needed to reabstract a loadable value into an existential and tried to maximally abstract it and thus store it into memory. The That code was never updated to make sure the value was at +1. So we would store a guaranteed value into memory and hope that whereever we stored it doesn't escape the current function. In this case, I believe that we would be safe... but past returns are not indicators of future results. rdar://40773543 SR-7858
1 parent 526632c commit d2e1bcd

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

lib/SILGen/SILGenConvert.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ ManagedValue SILGenFunction::emitExistentialErasure(
727727
ExistentialRepresentation::Boxed, *this);
728728
ManagedValue mv = F(SGFContext(&init));
729729
if (!mv.isInContext()) {
730-
mv.forwardInto(*this, loc, init.getAddress());
730+
mv.ensurePlusOne(*this, loc).forwardInto(*this, loc, init.getAddress());
731731
init.finishInitialization(*this);
732732
}
733733

test/SILGen/function_conversion.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,3 +641,27 @@ func rdar35702810_anyhashable() {
641641
// CHECK: convert_escape_to_noescape [not_guaranteed] [[PA]] : $@callee_guaranteed (@guaranteed Set<B>) -> () to $@noescape @callee_guaranteed (@guaranteed Set<B>) -> ()
642642
bar_set(type: B.self, fn_set)
643643
}
644+
645+
// ==== Function conversion with parameter substToOrig reabstraction.
646+
647+
struct FunctionConversionParameterSubstToOrigReabstractionTest {
648+
typealias SelfTy = FunctionConversionParameterSubstToOrigReabstractionTest
649+
650+
class Klass: Error {}
651+
652+
struct Foo<T> {
653+
static func enum1Func(_ : (T) -> Foo<Error>) -> Foo<Error> {
654+
// Just to make it compile.
655+
return Optional<Foo<Error>>.none!
656+
}
657+
}
658+
659+
static func bar<T>(t: T) -> Foo<T> {
660+
// Just to make it compile.
661+
return Optional<Foo<T>>.none!
662+
}
663+
664+
static func testFunc() -> Foo<Error> {
665+
return Foo<Klass>.enum1Func(SelfTy.bar)
666+
}
667+
}

0 commit comments

Comments
 (0)