Skip to content

Commit 92fab06

Browse files
committed
IRGen: fix generation of static enums with function payloads
fixes a compiler crash rdar://109999583
1 parent 8b82cc6 commit 92fab06

File tree

3 files changed

+64
-12
lines changed

3 files changed

+64
-12
lines changed

lib/IRGen/GenConstant.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ Explosion irgen::emitConstantValue(IRGenModule &IGM, SILValue operand,
336336
return llvm::ConstantExpr::getIntToPtr(val, sTy);
337337

338338
} else if (auto *CFI = dyn_cast<ConvertFunctionInst>(operand)) {
339-
return emitConstantValue(IGM, CFI->getOperand()).claimNextConstant();
339+
return emitConstantValue(IGM, CFI->getOperand());
340340

341341
} else if (auto *T2TFI = dyn_cast<ThinToThickFunctionInst>(operand)) {
342342
SILType type = operand->getType();
@@ -349,7 +349,12 @@ Explosion irgen::emitConstantValue(IRGenModule &IGM, SILValue operand,
349349
auto *context = llvm::ConstantExpr::getBitCast(
350350
llvm::ConstantPointerNull::get(IGM.OpaquePtrTy),
351351
sTy->getTypeAtIndex((unsigned)1));
352-
352+
353+
if (flatten) {
354+
Explosion out;
355+
out.add({function, context});
356+
return out;
357+
}
353358
return llvm::ConstantStruct::get(sTy, {function, context});
354359

355360
} else if (auto *FRI = dyn_cast<FunctionRefInst>(operand)) {

test/SILOptimizer/static_enums.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,37 @@ var outer: Outer? = Outer(i: Inner(x: 2, y: 3), z: 4)
130130
// CHECK-LABEL: sil_global hidden @$s4test8optionalSiSgvp : $Optional<Int> = {
131131
var optional: Int? = Optional(42)
132132

133+
struct StringGen {
134+
enum E {
135+
case none
136+
case str(String)
137+
case gen(() -> String)
138+
}
139+
140+
var source: E
141+
}
142+
143+
// CHECK-LABEL: sil_global hidden @$s4test3sg1AA9StringGenVvp : $StringGen = {
144+
var sg1 = StringGen(source: .gen({ "gen" }))
145+
146+
// CHECK-LABEL: sil_global hidden @$s4test3sg2AA9StringGenVvp : $StringGen = {
147+
var sg2 = StringGen(source: .none)
148+
149+
// CHECK-LABEL: sil_global hidden @$s4test3sg3AA9StringGenVvp : $StringGen = {
150+
var sg3 = StringGen(source: .str("str"))
151+
152+
@inline(never)
153+
func getStringGen(_ s: StringGen) -> String {
154+
switch s.source {
155+
case .gen(let f):
156+
return f()
157+
case .str(let s):
158+
return s
159+
case .none:
160+
return "none"
161+
}
162+
}
163+
133164
// CHECK-LABEL: sil_global private @$s4test9createArrSaySiSgGyFTv_ : $_ContiguousArrayStorage<Optional<Int>> = {
134165
@inline(never)
135166
func createArr() -> [Int?] {
@@ -197,6 +228,12 @@ struct Main {
197228
print("optional:", optional as Any)
198229
// CHECK-OUTPUT: createArr: [Optional(27), Optional(42), nil, Optional(103)]
199230
print("createArr:", createArr())
231+
// CHECK-OUTPUT: stringGen1: gen
232+
print("stringGen1: \(getStringGen(sg1))")
233+
// CHECK-OUTPUT: stringGen2: none
234+
print("stringGen2: \(getStringGen(sg2))")
235+
// CHECK-OUTPUT: stringGen3: str
236+
print("stringGen3: \(getStringGen(sg3))")
200237
}
201238
}
202239

validation-test/SILOptimizer/static_enums_fuzzing.swift

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func createTestfile() {
2222

2323
print()
2424

25-
for (idx, t) in globals.enumerated() {
25+
for (idx, _) in globals.enumerated() {
2626
print("""
2727
@inline(never) func printGlobal\(idx)() {
2828
print("global\(idx)var: \", global\(idx)var as Any)
@@ -79,6 +79,10 @@ var typeDefinitions: String {
7979
case C
8080
}
8181
82+
public func fn() {}
83+
84+
public typealias Func = () -> ()
85+
8286
"""
8387
}
8488

@@ -151,6 +155,16 @@ struct LargeString : Value {
151155
func getRuntimeTypeName(topLevel: Bool) -> String { topLevel ? "String" : "Swift.String" }
152156
}
153157

158+
struct Function : Value {
159+
160+
init(generator: inout RandomGenerator, depth: Int) {}
161+
162+
func getType() -> String { "Func" }
163+
func getInitValue() -> String { "fn" }
164+
func getRuntimeTypeName(topLevel: Bool) -> String { "() -> ()" }
165+
func getExpectedOutput(topLevel: Bool) -> String { "(Function)" }
166+
}
167+
154168
struct OptionalValue : Value {
155169

156170
let payload: any Value
@@ -340,23 +354,19 @@ struct RandomGenerator : RandomNumberGenerator {
340354
}
341355
}
342356

343-
private static let allValueTypes: [any Value.Type] = [
357+
private static let allTerminalTypes: [any Value.Type] = [
344358
SmallInt.self,
345359
LargeInt.self,
346360
SmallString.self,
347361
LargeString.self,
348-
Enum.self,
362+
Function.self,
363+
Enum.self
364+
]
365+
private static let allValueTypes: [any Value.Type] = allTerminalTypes + [
349366
OptionalValue.self,
350367
Struct.self,
351368
MultiPayloadEnum.self
352369
]
353370

354-
private static let allTerminalTypes: [any Value.Type] = [
355-
SmallInt.self,
356-
LargeInt.self,
357-
SmallString.self,
358-
LargeString.self,
359-
Enum.self
360-
]
361371
}
362372

0 commit comments

Comments
 (0)