Skip to content

Commit 34bfeb4

Browse files
authored
[C++ interop] Fix reflection info compiler crash. (#26438)
When a c++ namespace IRGens for reflection, it triggers a path that expects the namespace to have a particular form. Because it is always empty, we can treat it just like an empty swift enum.
1 parent 3691944 commit 34bfeb4

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

lib/IRGen/GenEnum.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5900,6 +5900,13 @@ EnumImplStrategy::get(TypeConverter &TC, SILType type, EnumDecl *theEnum) {
59005900
std::move(elementsWithNoPayload)));
59015901
}
59025902

5903+
// namespace-like enums must be imported as empty decls.
5904+
if (theEnum->hasClangNode() && numElements == 0 && !theEnum->isObjC()) {
5905+
return std::unique_ptr<EnumImplStrategy>(new SingletonEnumImplStrategy(
5906+
TC.IGM, tik, alwaysFixedSize, numElements,
5907+
std::move(elementsWithPayload), std::move(elementsWithNoPayload)));
5908+
}
5909+
59035910
// Enums imported from Clang or marked with @objc use C-compatible layout.
59045911
if (theEnum->hasClangNode() || theEnum->isObjC()) {
59055912
assert(elementsWithPayload.empty() && "C enum with payload?!");

lib/IRGen/GenReflection.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,11 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
607607
}
608608

609609
void layout() override {
610-
assert(!NTD->hasClangNode() || isa<StructDecl>(NTD));
610+
if (NTD->hasClangNode()) {
611+
auto *enumDecl = dyn_cast<EnumDecl>(NTD);
612+
// Structs and namespace-like enums are ok.
613+
assert(isa<StructDecl>(NTD) || (enumDecl && !enumDecl->hasCases()));
614+
}
611615

612616
PrettyStackTraceDecl DebugStack("emitting field type metadata", NTD);
613617
addNominalRef(NTD);

test/ClangImporter/cxx_interop_ir.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ func indirectUsage() {
99
useT(makeT())
1010
}
1111

12+
// CHECK-LABEL: define hidden swiftcc %swift.type* @"$s6cxx_ir14reflectionInfo3argypXpSo2nsV1TV_tF"
13+
// CHECK: %0 = call swiftcc %swift.metadata_response @"$sSo2nsV1TVMa"({{i64|i32}} 0)
14+
func reflectionInfo(arg: namespacedT) -> Any.Type {
15+
return type(of: arg)
16+
}
17+
1218
// CHECK: define hidden swiftcc void @"$s6cxx_ir24namespaceManglesIntoName3argySo2nsV1TV_tF"
1319
func namespaceManglesIntoName(arg: namespacedT) {
1420
}

0 commit comments

Comments
 (0)