Skip to content

Commit a69656f

Browse files
authored
[Serialization] Don't crash if we can't get the type for an XREF (#12914)
If we can't resolve a cross-reference unambiguously, we're supposed to produce an llvm::Error and let the calling code handle it. However, if we couldn't even resolve the /type/ of the cross-reference, we would just crash. Follow the supported error path in that case too -- in many cases the error can just propagate upwards to something that can handle it. rdar://problem/34821187, plus an extra test case from rdar://problem/35157494. (The latter will be fixed better later, but meanwhile let's not regress on the crashing part.)
1 parent c7f1df4 commit a69656f

File tree

3 files changed

+70
-4
lines changed

3 files changed

+70
-4
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,9 +1277,18 @@ ModuleFile::resolveCrossReference(ModuleDecl *baseModule, uint32_t pathLen) {
12771277
DeclBaseName name = getDeclBaseName(IID);
12781278
pathTrace.addValue(name);
12791279

1280-
Type filterTy = getType(TID);
1281-
if (!isType)
1280+
Type filterTy;
1281+
if (!isType) {
1282+
auto maybeType = getTypeChecked(TID);
1283+
if (!maybeType) {
1284+
// FIXME: Don't throw away the inner error's information.
1285+
llvm::consumeError(maybeType.takeError());
1286+
return llvm::make_error<XRefError>("couldn't decode type",
1287+
pathTrace, name);
1288+
}
1289+
filterTy = maybeType.get();
12821290
pathTrace.addType(filterTy);
1291+
}
12831292

12841293
baseModule->lookupQualified(ModuleType::get(baseModule), name,
12851294
NL_QualifiedDefault | NL_KnownNoDependency,
@@ -1482,9 +1491,18 @@ ModuleFile::resolveCrossReference(ModuleDecl *baseModule, uint32_t pathLen) {
14821491

14831492
pathTrace.addValue(memberName);
14841493

1485-
Type filterTy = getType(TID);
1486-
if (!isType)
1494+
Type filterTy;
1495+
if (!isType) {
1496+
auto maybeType = getTypeChecked(TID);
1497+
if (!maybeType) {
1498+
// FIXME: Don't throw away the inner error's information.
1499+
llvm::consumeError(maybeType.takeError());
1500+
return llvm::make_error<XRefError>("couldn't decode type",
1501+
pathTrace, memberName);
1502+
}
1503+
filterTy = maybeType.get();
14871504
pathTrace.addType(filterTy);
1505+
}
14881506

14891507
if (values.size() != 1) {
14901508
return llvm::make_error<XRefError>("multiple matching base values",

test/Serialization/Recovery/Inputs/custom-modules/Overrides.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,22 @@
115115
//- (nonnull instancetype)initWithValue:(long)value;
116116
#endif
117117
@end
118+
119+
120+
#if !BAD
121+
struct BoxedInt {
122+
int value;
123+
};
124+
#endif
125+
126+
@interface MethodWithDisappearingType : Object
127+
#if !BAD
128+
- (struct BoxedInt)boxItUp;
129+
#endif
130+
@end
131+
132+
@interface InitializerWithDisappearingType : Object
133+
#if !BAD
134+
- (nonnull instancetype)initWithBoxedInt:(struct BoxedInt)box;
135+
#endif
136+
@end

test/Serialization/Recovery/overrides.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,4 +311,33 @@ open class D9_UnknownInitDisappearsRequiredGrandchild : D8_UnknownInitDisappears
311311
// CHECK-RECOVERY-NEXT: /* placeholder for init(value:) */
312312
// CHECK-RECOVERY-NEXT: {{^}$}}
313313

314+
public class E1_MethodWithDisappearingType : MethodWithDisappearingType {
315+
public override func boxItUp() -> BoxedInt { fatalError() }
316+
}
317+
318+
// CHECK-LABEL: class E1_MethodWithDisappearingType : MethodWithDisappearingType {
319+
// CHECK-NEXT: override func boxItUp() -> BoxedInt
320+
// CHECK-NEXT: init()
321+
// CHECK-NEXT: {{^}$}}
322+
323+
// CHECK-RECOVERY-LABEL: class E1_MethodWithDisappearingType : MethodWithDisappearingType {
324+
// CHECK-RECOVERY-NEXT: init()
325+
// CHECK-RECOVERY-NEXT: {{^}$}}
326+
327+
public class E2_InitializerStub : InitializerWithDisappearingType {
328+
public init(unrelatedValue: Int) { fatalError() }
329+
}
330+
331+
// CHECK-LABEL: class E2_InitializerStub : InitializerWithDisappearingType {
332+
// CHECK-NEXT: init(unrelatedValue: Int)
333+
// CHECK-NEXT: init(boxedInt box: BoxedInt)
334+
// CHECK-NEXT: init()
335+
// CHECK-NEXT: {{^}$}}
336+
337+
// CHECK-RECOVERY-LABEL: class E2_InitializerStub : InitializerWithDisappearingType {
338+
// CHECK-RECOVERY-NEXT: init(unrelatedValue: Int)
339+
// CHECK-RECOVERY-NEXT: /* placeholder for init(boxedInt:) */
340+
// CHECK-RECOVERY-NEXT: init()
341+
// CHECK-RECOVERY-NEXT: {{^}$}}
342+
314343
#endif // TEST

0 commit comments

Comments
 (0)