Skip to content

Commit a97cdc4

Browse files
Merge pull request #25216 from aschwaighofer/fix_getSingletonAggregateFieldType
IRGen: getSingletonAggregateFieldType must not return field if its ac…
2 parents 4b9771c + bec3898 commit a97cdc4

File tree

3 files changed

+62
-4
lines changed

3 files changed

+62
-4
lines changed

lib/IRGen/GenType.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,8 +2289,17 @@ SILType irgen::getSingletonAggregateFieldType(IRGenModule &IGM, SILType t,
22892289
auto allFields = structDecl->getStoredProperties();
22902290

22912291
auto field = allFields.begin();
2292-
if (!allFields.empty() && std::next(field) == allFields.end())
2293-
return t.getFieldType(*field, IGM.getSILModule());
2292+
if (!allFields.empty() && std::next(field) == allFields.end()) {
2293+
auto fieldTy = t.getFieldType(*field, IGM.getSILModule());
2294+
if (auto fieldDecl = fieldTy.getNominalOrBoundGenericNominal()) {
2295+
// The field's access level must be higher or equal to the enclosing
2296+
// struct's.
2297+
if (fieldDecl->getEffectiveAccess() >= structDecl->getEffectiveAccess())
2298+
return fieldTy;
2299+
} else {
2300+
return fieldTy;
2301+
}
2302+
}
22942303

22952304
return SILType();
22962305
}
@@ -2305,8 +2314,17 @@ SILType irgen::getSingletonAggregateFieldType(IRGenModule &IGM, SILType t,
23052314

23062315
auto theCase = allCases.begin();
23072316
if (!allCases.empty() && std::next(theCase) == allCases.end()
2308-
&& (*theCase)->hasAssociatedValues())
2309-
return t.getEnumElementType(*theCase, IGM.getSILModule());
2317+
&& (*theCase)->hasAssociatedValues()) {
2318+
auto enumEltTy = t.getEnumElementType(*theCase, IGM.getSILModule());
2319+
if (auto eltDecl = enumEltTy.getNominalOrBoundGenericNominal()) {
2320+
// The enum element's access level must be higher or equal to the
2321+
// enclosing struct's.
2322+
if (eltDecl->getEffectiveAccess() >= enumDecl->getEffectiveAccess())
2323+
return enumEltTy;
2324+
} else {
2325+
return enumEltTy;
2326+
}
2327+
}
23102328

23112329
return SILType();
23122330
}

test/IRGen/Inputs/metadata2.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import resilient_struct
2+
3+
struct Item {
4+
var d: ResilientInt? = nil
5+
}
6+
7+
struct InternalContainer {
8+
9+
fileprivate enum SomeEnumType {
10+
case none
11+
case single(Item)
12+
13+
init(item: [Item]) {
14+
if item.count >= 1 {
15+
self = .single(item.first!)
16+
} else {
17+
self = .none
18+
}
19+
}
20+
}
21+
private var type: SomeEnumType
22+
23+
init(item: [Item]) {
24+
self.type = SomeEnumType(item: item)
25+
}
26+
}

test/IRGen/metadata.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
3+
// RUN: %target-swift-frontend -module-name A -I %t %S/Inputs/metadata2.swift -primary-file %s -emit-ir | %FileCheck %s
4+
5+
// CHECK-LABEL: define {{.*}}swiftcc %swift.metadata_response @"$s1A12MyControllerCMr"(%swift.type*, i8*, i8**)
6+
// CHECK-NOT: ret
7+
// CHECK: call swiftcc %swift.metadata_response @"$s1A17InternalContainerVMa"(
8+
// CHECK: ret
9+
class MyController {
10+
var c = InternalContainer(item: [])
11+
func update(_ n: InternalContainer) {
12+
c = n
13+
}
14+
}

0 commit comments

Comments
 (0)