Skip to content

Commit 9f2b7c4

Browse files
committed
Fix indexing crasher with implicit objcImpl inits
Implicit initializers are given a source location within the type they belong to. This works poorly for @objc @implementation classes, because the class they belong to is imported and so those SourceLocs are in a different source buffer from the extension they’re inside, breaking an invariant enforced by index-while-building features. Fix these SourceLocs to come from the implementation context, so they’ll come from the extension for an objcImpl class and the type itself otherwise.
1 parent e689ad3 commit 9f2b7c4

File tree

4 files changed

+26
-6
lines changed

4 files changed

+26
-6
lines changed

include/swift/AST/DeclContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,8 @@ class IterableDeclContext {
858858
return LastDeclAndKind.getInt();
859859
}
860860

861+
SourceRange getBraces() const;
862+
861863
bool hasUnparsedMembers() const;
862864

863865
void setDeserializedMembers(bool deserialized) { DeserializedMembers = deserialized; }

lib/AST/DeclContext.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,18 @@ ASTContext &IterableDeclContext::getASTContext() const {
919919
return getDecl()->getASTContext();
920920
}
921921

922+
SourceRange IterableDeclContext::getBraces() const {
923+
switch (getIterableContextKind()) {
924+
case IterableDeclContextKind::NominalTypeDecl:
925+
return cast<NominalTypeDecl>(this)->getBraces();
926+
break;
927+
928+
case IterableDeclContextKind::ExtensionDecl:
929+
return cast<ExtensionDecl>(this)->getBraces();
930+
break;
931+
}
932+
}
933+
922934
DeclRange IterableDeclContext::getCurrentMembersWithoutLoading() const {
923935
return DeclRange(FirstDeclAndLazyMembers.getPointer(), nullptr);
924936
}

lib/Sema/CodeSynthesis.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
288288
ASTContext &ctx) {
289289
assert(!decl->hasClangNode());
290290

291-
SourceLoc Loc = decl->getLoc();
291+
SourceLoc Loc = decl->getImplementationContext()->getDecl()->getLoc();
292292
auto accessLevel = AccessLevel::Internal;
293293

294294
// Determine the parameter type of the implicit constructor.
@@ -818,16 +818,16 @@ createDesignatedInitOverride(ClassDecl *classDecl,
818818

819819
// Create the initializer declaration, inheriting the name,
820820
// failability, and throws from the superclass initializer.
821-
auto implCtx = classDecl->getImplementationContext()->getAsGenericContext();
821+
auto implCtx = classDecl->getImplementationContext();
822822
auto ctor = new (ctx) ConstructorDecl(
823-
superclassCtor->getName(), classDecl->getBraces().Start,
823+
superclassCtor->getName(), implCtx->getBraces().Start,
824824
superclassCtor->isFailable(),
825825
/*FailabilityLoc=*/SourceLoc(),
826826
/*Async=*/superclassCtor->hasAsync(),
827827
/*AsyncLoc=*/SourceLoc(),
828828
/*Throws=*/superclassCtor->hasThrows(),
829829
/*ThrowsLoc=*/SourceLoc(), TypeLoc::withoutLoc(thrownType), bodyParams,
830-
genericParams, implCtx,
830+
genericParams, implCtx->getAsGenericContext(),
831831
/*LifetimeDependentTypeRepr*/ nullptr);
832832

833833
ctor->setImplicit();

test/Index/index_objc_impl.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
// RUN: %empty-directory(%t/mods)
55
// RUN: split-file %s %t
66

7-
// RUN: %target-swift-frontend -emit-module -o %t/mods %t/ObjcImpl.swift -import-objc-header %t/objc_impl.h -disable-objc-attr-requires-foundation-module -target %target-stable-abi-triple
7+
// We use `-index-store-path` to exercise a code path that used to crash; we
8+
// aren't checking its output.
9+
// RUN: %target-swift-frontend -emit-module -o %t/mods %t/ObjcImpl.swift -import-objc-header %t/objc_impl.h -target %target-stable-abi-triple -disable-objc-attr-requires-foundation-module -index-store-path %t/index-store
810
// RUN: %target-swift-ide-test -print-indexed-symbols -module-to-print ObjcImpl -source-filename none -I %t/mods -target %target-stable-abi-triple | %FileCheck %s
911

1012
//--- objc_impl.h
1113
@interface NSObject
14+
- (instancetype)init;
1215
@end
1316

1417
@interface ObjCClass : NSObject
@@ -20,5 +23,8 @@
2023
// CHECK: class/Swift | ObjCClass | c:objc(cs)ObjCClass | Ref
2124
@_objcImplementation public extension ObjCClass {
2225
// CHECK: instance-property/Swift | someObjCDeclaredVar | c:@CM@ObjcImpl@@objc(cs)ObjCClass(py)someObjCDeclaredVar | Def
23-
@objc var someObjCDeclaredVar: CInt
26+
@objc var someObjCDeclaredVar: CInt = 1
27+
28+
// Implicitly synthesized `override init()`:
29+
// CHECK: constructor/Swift | init() | c:@CM@ObjcImpl@@objc(cs)ObjCClass(im)init | Def
2430
}

0 commit comments

Comments
 (0)