Skip to content

Commit aea6f06

Browse files
authored
Merge pull request #17182 from aschwaighofer/irgen_dont_outline_opened_exist_enum
2 parents 73ca2f4 + 448b6b3 commit aea6f06

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

lib/IRGen/GenEnum.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2326,6 +2326,29 @@ namespace {
23262326
llvm_unreachable("ABI-inaccessible type cannot be loadable");
23272327

23282328
case Normal: {
2329+
if (loweredType.hasOpenedExistential()) {
2330+
EnumPayload payload;
2331+
llvm::Value *extraTag;
2332+
std::tie(payload, extraTag) =
2333+
getPayloadAndExtraTagFromExplosion(IGF, src);
2334+
llvm::BasicBlock *endBB =
2335+
testFixedEnumContainsPayload(IGF, payload, extraTag);
2336+
2337+
if (PayloadBitCount > 0) {
2338+
ConditionalDominanceScope condition(IGF);
2339+
Explosion payloadValue;
2340+
Explosion payloadCopy;
2341+
auto &loadableTI = getLoadablePayloadTypeInfo();
2342+
loadableTI.unpackFromEnumPayload(IGF, payload, payloadValue, 0);
2343+
loadableTI.copy(IGF, payloadValue, payloadCopy,
2344+
IGF.getDefaultAtomicity());
2345+
(void)payloadCopy.claimAll();
2346+
}
2347+
IGF.Builder.CreateBr(endBB);
2348+
IGF.Builder.emitBlock(endBB);
2349+
return;
2350+
}
2351+
23292352
if (!copyEnumFunction)
23302353
copyEnumFunction = emitCopyEnumFunction(IGF.IGM, loweredType);
23312354
Explosion tmp;
@@ -2363,6 +2386,27 @@ namespace {
23632386
llvm_unreachable("ABI-inaccessible type cannot be loadable");
23642387

23652388
case Normal: {
2389+
if (loweredType.hasOpenedExistential()) {
2390+
EnumPayload payload;
2391+
llvm::Value *extraTag;
2392+
std::tie(payload, extraTag) =
2393+
getPayloadAndExtraTagFromExplosion(IGF, src);
2394+
llvm::BasicBlock *endBB =
2395+
testFixedEnumContainsPayload(IGF, payload, extraTag);
2396+
2397+
// If we did, consume it.
2398+
if (PayloadBitCount > 0) {
2399+
ConditionalDominanceScope condition(IGF);
2400+
Explosion payloadValue;
2401+
auto &loadableTI = getLoadablePayloadTypeInfo();
2402+
loadableTI.unpackFromEnumPayload(IGF, payload, payloadValue, 0);
2403+
loadableTI.consume(IGF, payloadValue, IGF.getDefaultAtomicity());
2404+
}
2405+
2406+
IGF.Builder.CreateBr(endBB);
2407+
IGF.Builder.emitBlock(endBB);
2408+
return;
2409+
}
23662410
if (!consumeEnumFunction)
23672411
consumeEnumFunction = emitConsumeEnumFunction(IGF.IGM, loweredType);
23682412
Explosion tmp;
@@ -4068,6 +4112,22 @@ namespace {
40684112

40694113
case BitwiseTakable:
40704114
case Normal: {
4115+
if (loweredType.hasOpenedExistential()) {
4116+
auto parts = destructureAndTagLoadableEnum(IGF, src);
4117+
4118+
forNontrivialPayloads(
4119+
IGF, parts.tag,
4120+
[&](unsigned tagIndex, EnumImplStrategy::Element elt) {
4121+
auto &lti = cast<LoadableTypeInfo>(*elt.ti);
4122+
Explosion value;
4123+
projectPayloadValue(IGF, parts.payload, tagIndex, lti, value);
4124+
4125+
Explosion tmp;
4126+
lti.copy(IGF, value, tmp, IGF.getDefaultAtomicity());
4127+
(void)tmp.claimAll(); // FIXME: repack if not bit-identical
4128+
});
4129+
return;
4130+
}
40714131
if (!copyEnumFunction)
40724132
copyEnumFunction = emitCopyEnumFunction(IGF.IGM, loweredType);
40734133
Explosion tmp;
@@ -4113,6 +4173,20 @@ namespace {
41134173

41144174
case BitwiseTakable:
41154175
case Normal: {
4176+
if (loweredType.hasOpenedExistential()) {
4177+
auto parts = destructureAndTagLoadableEnum(IGF, src);
4178+
4179+
forNontrivialPayloads(
4180+
IGF, parts.tag,
4181+
[&](unsigned tagIndex, EnumImplStrategy::Element elt) {
4182+
auto &lti = cast<LoadableTypeInfo>(*elt.ti);
4183+
Explosion value;
4184+
projectPayloadValue(IGF, parts.payload, tagIndex, lti, value);
4185+
4186+
lti.consume(IGF, value, IGF.getDefaultAtomicity());
4187+
});
4188+
return;
4189+
}
41164190
if (!consumeEnumFunction)
41174191
consumeEnumFunction = emitConsumeEnumFunction(IGF.IGM, loweredType);
41184192
Explosion tmp;

test/IRGen/outlined_copy_addr.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,20 @@ func testIt<P: BaseProt>(_ f: GenericError<P>?) {
5858
func dontCrash<P: BaseProt>(_ f: GenericError<P>) {
5959
testIt(f)
6060
}
61+
62+
protocol Baz : class {
63+
}
64+
extension Baz {
65+
static func crash(setup: ((Self) -> ())?){
66+
}
67+
}
68+
class Foobar {
69+
public static func dontCrash() -> Baz? {
70+
let cls : Baz.Type = Foobar1.self
71+
// This used to crash because we tried to outline the optional consume with
72+
// an opened payload existential type.
73+
cls.crash(setup: { (arg: Baz) -> () in })
74+
return nil
75+
}
76+
}
77+
class Foobar1 : Foobar, Baz { }

0 commit comments

Comments
 (0)