Skip to content

Commit 79e07c7

Browse files
committed
[di] DI assumes that all structs it analyzes will have /1/ property... this is not always true =><=.
The culprit here is NSManagedObject subclasses that only have @NSManaged attributes. This doesn't affect predictable mem opts since this issue is in the DIMemoryUseCollector that only affects DI and that I have removed. rdar://34589327
1 parent 634f719 commit 79e07c7

File tree

3 files changed

+67
-11
lines changed

3 files changed

+67
-11
lines changed

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ static SILType getElementTypeRec(SILModule &Module, SILType T, unsigned EltNo) {
7979
return getElementTypeRec(Module, FieldType, EltNo);
8080
EltNo -= NumFieldElements;
8181
}
82+
// This can only happen if we look at a symbolic element number of an empty
83+
// tuple.
8284
llvm::report_fatal_error("invalid element number");
8385
}
8486

lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ static unsigned getElementCountRec(SILModule &Module, SILType T,
4949
if (IsSelfOfNonDelegatingInitializer) {
5050
// Protocols never have a stored properties.
5151
if (auto *NTD = T.getNominalOrBoundGenericNominal()) {
52-
5352
unsigned NumElements = 0;
5453
for (auto *VD : NTD->getStoredProperties())
5554
NumElements +=
@@ -137,6 +136,8 @@ static SILType getElementTypeRec(SILModule &Module, SILType T, unsigned EltNo,
137136
return getElementTypeRec(Module, FieldType, EltNo, false);
138137
EltNo -= NumFieldElements;
139138
}
139+
// This can only happen if we look at a symbolic element number of an empty
140+
// tuple.
140141
llvm::report_fatal_error("invalid element number");
141142
}
142143

@@ -145,14 +146,22 @@ static SILType getElementTypeRec(SILModule &Module, SILType T, unsigned EltNo,
145146
// for each of the tuple members.
146147
if (IsSelfOfNonDelegatingInitializer) {
147148
if (auto *NTD = T.getNominalOrBoundGenericNominal()) {
149+
bool HasStoredProperties = false;
148150
for (auto *VD : NTD->getStoredProperties()) {
151+
HasStoredProperties = true;
149152
auto FieldType = T.getFieldType(VD, Module);
150153
unsigned NumFieldElements =
151154
getElementCountRec(Module, FieldType, false);
152155
if (EltNo < NumFieldElements)
153156
return getElementTypeRec(Module, FieldType, EltNo, false);
154157
EltNo -= NumFieldElements;
155158
}
159+
160+
// If we do not have any stored properties and were passed an EltNo of 0,
161+
// just return self.
162+
if (!HasStoredProperties && EltNo == 0) {
163+
return T;
164+
}
156165
llvm::report_fatal_error("invalid element number");
157166
}
158167
}
@@ -206,22 +215,26 @@ SILValue DIMemoryObjectInfo::emitElementAddress(
206215
// lifetimes for each of the tuple members.
207216
if (IsSelf) {
208217
if (auto *NTD = PointeeType.getNominalOrBoundGenericNominal()) {
209-
// If we have a class, we can use a borrow directly and avoid ref count
210-
// traffic.
211-
if (isa<ClassDecl>(NTD) && Ptr->getType().isAddress()) {
212-
SILValue Original = Ptr;
213-
SILValue Borrowed = Ptr = B.createLoadBorrow(Loc, Ptr);
214-
EndBorrowList.emplace_back(Borrowed, Original);
215-
}
216-
218+
bool HasStoredProperties = false;
217219
for (auto *VD : NTD->getStoredProperties()) {
220+
if (!HasStoredProperties) {
221+
HasStoredProperties = true;
222+
// If we have a class, we can use a borrow directly and avoid ref
223+
// count traffic.
224+
if (isa<ClassDecl>(NTD) && Ptr->getType().isAddress()) {
225+
SILValue Original = Ptr;
226+
SILValue Borrowed = Ptr = B.createLoadBorrow(Loc, Ptr);
227+
EndBorrowList.emplace_back(Borrowed, Original);
228+
}
229+
}
230+
218231
auto FieldType = PointeeType.getFieldType(VD, Module);
219232
unsigned NumFieldElements =
220233
getElementCountRec(Module, FieldType, false);
221234
if (EltNo < NumFieldElements) {
222-
if (isa<StructDecl>(NTD))
235+
if (isa<StructDecl>(NTD)) {
223236
Ptr = B.createStructElementAddr(Loc, Ptr, VD);
224-
else {
237+
} else {
225238
assert(isa<ClassDecl>(NTD));
226239
SILValue Original, Borrowed;
227240
if (Ptr.getOwnershipKind() != ValueOwnershipKind::Guaranteed) {
@@ -241,6 +254,12 @@ SILValue DIMemoryObjectInfo::emitElementAddress(
241254
}
242255
EltNo -= NumFieldElements;
243256
}
257+
258+
if (!HasStoredProperties) {
259+
assert(EltNo == 0 && "Element count problem");
260+
return Ptr;
261+
}
262+
244263
continue;
245264
}
246265
}
@@ -301,7 +320,9 @@ DIMemoryObjectInfo::getPathStringToElement(unsigned Element,
301320
// If this is indexing into a field of 'self', look it up.
302321
if (isNonDelegatingInit() && !isDerivedClassSelfOnly()) {
303322
if (auto *NTD = MemorySILType.getNominalOrBoundGenericNominal()) {
323+
bool HasStoredProperty = false;
304324
for (auto *VD : NTD->getStoredProperties()) {
325+
HasStoredProperty = true;
305326
auto FieldType = MemorySILType.getFieldType(VD, Module);
306327
unsigned NumFieldElements =
307328
getElementCountRec(Module, FieldType, false);
@@ -313,6 +334,10 @@ DIMemoryObjectInfo::getPathStringToElement(unsigned Element,
313334
}
314335
Element -= NumFieldElements;
315336
}
337+
338+
// If we do not have any stored properties, we have nothing of interest.
339+
if (!HasStoredProperty)
340+
return nullptr;
316341
}
317342
}
318343

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -I %S/../ClangImporter/Inputs/custom-modules %s -emit-sil -enable-sil-ownership
2+
3+
// REQUIRES: objc_interop
4+
5+
// Make sure if we have an NSManagedObject without stored properties that DI
6+
// does not crash or emit an error.
7+
8+
import Foundation
9+
import CoreData
10+
11+
class Person : NSManagedObject {
12+
enum MyError : Error {
13+
case error
14+
}
15+
16+
static func myThrow() throws {}
17+
static func myBool() -> Bool { return false }
18+
public required init(_ x: Int) throws {
19+
if Person.myBool() {
20+
throw MyError.error
21+
}
22+
super.init()
23+
try Person.myThrow()
24+
}
25+
}
26+
27+
extension Person {
28+
@NSManaged var name: String
29+
}

0 commit comments

Comments
 (0)