Skip to content

Commit d924be3

Browse files
authored
Merge pull request #18501 from jckarter/block-silgen-crash-41056468
SILGen: Handle reabstraction in attempted +0 argument peephole.
2 parents 29f71cd + 197f628 commit d924be3

File tree

3 files changed

+43
-6
lines changed

3 files changed

+43
-6
lines changed

cmake/modules/DarwinSDKs.cmake

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1+
option(SWIFT_ENABLE_IOS32
2+
"Build 32-bit variants of iOS"
3+
TRUE)
4+
5+
if(SWIFT_ENABLE_IOS32)
16
set(SUPPORTED_IOS_ARCHS "armv7;armv7s;arm64")
27
set(SUPPORTED_IOS_SIMULATOR_ARCHS "i386;x86_64")
8+
else()
9+
set(SUPPORTED_IOS_ARCHS "arm64")
10+
set(SUPPORTED_IOS_SIMULATOR_ARCHS "x86_64")
11+
endif()
12+
313
set(SUPPORTED_TVOS_ARCHS "arm64")
414
set(SUPPORTED_TVOS_SIMULATOR_ARCHS "x86_64")
515
set(SUPPORTED_WATCHOS_ARCHS "armv7k")

lib/SILGen/SILGenExpr.cpp

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

11201120
// If the base is a reference type, just handle this as loading the lvalue.
1121+
ManagedValue result;
11211122
if (baseFormalType->hasReferenceSemantics()) {
11221123
LValue LV = emitPropertyLValue(loc, base, baseFormalType, field,
11231124
LValueOptions(), AccessKind::Read,
11241125
AccessSemantics::DirectToStorage);
1125-
return emitLoadOfLValue(loc, std::move(LV), C, isBaseGuaranteed);
1126-
}
1127-
1128-
ManagedValue result;
1129-
if (!base.getType().isAddress()) {
1126+
auto loaded = emitLoadOfLValue(loc, std::move(LV), C, isBaseGuaranteed);
1127+
// If we don't have to reabstract, the load is sufficient.
1128+
if (!hasAbstractionChange)
1129+
return loaded;
1130+
1131+
// Otherwise, bring the component up to +1 so we can reabstract it.
1132+
result = std::move(loaded).getAsSingleValue(*this, loc)
1133+
.copyUnmanaged(*this, loc);
1134+
} else if (!base.getType().isAddress()) {
11301135
// For non-address-only structs, we emit a struct_extract sequence.
11311136
result = B.createStructExtract(loc, base, field);
11321137

@@ -2361,7 +2366,7 @@ class NominalTypeMemberRefRValueEmitter {
23612366
// If the field is not a let, bail. We need to use the lvalue logic.
23622367
if (!Field->isLet())
23632368
return None;
2364-
2369+
23652370
// If we are emitting a delegating init super and we have begun the
23662371
// super.init call, since self has been exclusively borrowed, we need to be
23672372
// 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-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)