Skip to content

Commit 3c2eb97

Browse files
authored
Merge pull request #18502 from jckarter/block-silgen-crash-41056468-4.2
[4.2] SILGen: Handle reabstraction in attempted +0 argument peephole.
2 parents bb9487f + a2f3af8 commit 3c2eb97

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,15 +1270,20 @@ RValue SILGenFunction::emitRValueForStorageLoad(
12701270
}
12711271

12721272
// If the base is a reference type, just handle this as loading the lvalue.
1273+
ManagedValue result;
12731274
if (baseFormalType->hasReferenceSemantics()) {
12741275
LValue LV = emitPropertyLValue(loc, base, baseFormalType, field,
12751276
LValueOptions(), AccessKind::Read,
12761277
AccessSemantics::DirectToStorage);
1277-
return emitLoadOfLValue(loc, std::move(LV), C, isBaseGuaranteed);
1278-
}
1279-
1280-
ManagedValue result;
1281-
if (!base.getType().isAddress()) {
1278+
auto loaded = emitLoadOfLValue(loc, std::move(LV), C, isBaseGuaranteed);
1279+
// If we don't have to reabstract, the load is sufficient.
1280+
if (!hasAbstractionChange)
1281+
return loaded;
1282+
1283+
// Otherwise, bring the component up to +1 so we can reabstract it.
1284+
result = std::move(loaded).getAsSingleValue(*this, loc)
1285+
.copyUnmanaged(*this, loc);
1286+
} else if (!base.getType().isAddress()) {
12821287
// For non-address-only structs, we emit a struct_extract sequence.
12831288
result = B.createStructExtract(loc, base, field);
12841289

@@ -2511,7 +2516,7 @@ class NominalTypeMemberRefRValueEmitter {
25112516
// If the field is not a let, bail. We need to use the lvalue logic.
25122517
if (!Field->isLet())
25132518
return None;
2514-
2519+
25152520
// If we are emitting a delegating init super and we have begun the
25162521
// super.init call, since self has been exclusively borrowed, we need to be
25172522
// conservative and use the lvalue machinery. This ensures that we properly
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-swift-frontend -emit-silgen -enable-sil-ownership -verify %s
2+
class BlockBox<T> {
3+
let block: (T) -> Void = { _ in }
4+
5+
var computedBlock: (T) -> Void { return { _ in } }
6+
}
7+
8+
struct BlockStruct<T> {
9+
let block: (T) -> Void = { _ in }
10+
var computedBlock: (T) -> Void { return { _ in } }
11+
}
12+
13+
func escapingCompletion(completion: @escaping (String) -> Void) {}
14+
15+
func foo(box: BlockBox<String>) {
16+
escapingCompletion(completion: box.block)
17+
escapingCompletion(completion: box.computedBlock)
18+
}
19+
func foo(struc: BlockStruct<String>) {
20+
escapingCompletion(completion: struc.block)
21+
escapingCompletion(completion: struc.computedBlock)
22+
}

0 commit comments

Comments
 (0)