[AST] Fix crashes caused by redeclarations in hidden prototypes
ObjCContainerDecl.getMethod returns a nullptr by default when the container is a hidden prototype. Callsites where the method is being looked up on the redeclaration's own container should skip this check since they (rightly) expect a valid method to be found. Resolves rdar://69444243 Reviewed By: akyrtzi Differential Revision: https://reviews.llvm.org/D89024
This commit is contained in:
parent
8a5858c8fd
commit
fbb499ef25
|
@ -950,7 +950,8 @@ ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {
|
||||||
if (!Redecl && isRedeclaration()) {
|
if (!Redecl && isRedeclaration()) {
|
||||||
// This is the last redeclaration, go back to the first method.
|
// This is the last redeclaration, go back to the first method.
|
||||||
return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
|
return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
|
||||||
isInstanceMethod());
|
isInstanceMethod(),
|
||||||
|
/*AllowHidden=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Redecl ? Redecl : this;
|
return Redecl ? Redecl : this;
|
||||||
|
@ -983,7 +984,8 @@ ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
|
||||||
if (isRedeclaration()) {
|
if (isRedeclaration()) {
|
||||||
// It is possible that we have not done deserializing the ObjCMethod yet.
|
// It is possible that we have not done deserializing the ObjCMethod yet.
|
||||||
ObjCMethodDecl *MD =
|
ObjCMethodDecl *MD =
|
||||||
cast<ObjCContainerDecl>(CtxD)->getMethod(Sel, isInstanceMethod());
|
cast<ObjCContainerDecl>(CtxD)->getMethod(Sel, isInstanceMethod(),
|
||||||
|
/*AllowHidden=*/true);
|
||||||
return MD ? MD : this;
|
return MD ? MD : this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1308,8 +1310,9 @@ void ObjCMethodDecl::getOverriddenMethods(
|
||||||
const ObjCMethodDecl *Method = this;
|
const ObjCMethodDecl *Method = this;
|
||||||
|
|
||||||
if (Method->isRedeclaration()) {
|
if (Method->isRedeclaration()) {
|
||||||
Method = cast<ObjCContainerDecl>(Method->getDeclContext())->
|
Method = cast<ObjCContainerDecl>(Method->getDeclContext())
|
||||||
getMethod(Method->getSelector(), Method->isInstanceMethod());
|
->getMethod(Method->getSelector(), Method->isInstanceMethod(),
|
||||||
|
/*AllowHidden=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Method->isOverriding()) {
|
if (Method->isOverriding()) {
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
@protocol P1
|
||||||
|
- (void)p1_method;
|
||||||
|
- (void)p1_method;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface Foo (SubP1) <P1>
|
||||||
|
@end
|
|
@ -0,0 +1,3 @@
|
||||||
|
@interface Foo
|
||||||
|
- (void)parent_method;
|
||||||
|
@end
|
|
@ -20,3 +20,11 @@ module PreambleWithImplicitImport {
|
||||||
export *
|
export *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module hidden_redecls {
|
||||||
|
header "hidden-redecls.h"
|
||||||
|
|
||||||
|
explicit module sub {
|
||||||
|
header "hidden-redecls-sub.h"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
@import hidden_redecls;
|
||||||
|
|
||||||
|
@interface Foo (Top)
|
||||||
|
- (void)top_method;
|
||||||
|
@end
|
||||||
|
|
||||||
|
// p1_method in protocol P1 is hidden since module_redecls.sub hasn't been
|
||||||
|
// imported yet. Check it is still indexed.
|
||||||
|
|
||||||
|
// RUN: c-index-test -index-file-full %s -isystem %S/Inputs -fmodules -target x86_64-apple-macosx10.7 | FileCheck %s
|
||||||
|
// CHECK: [indexDeclaration]: kind: objc-instance-method | name: p1_method | {{.*}} | loc: {{.*}}hidden-redecls-sub.h:2:9 | {{.*}} | isRedecl: 0
|
||||||
|
// CHECK: [indexDeclaration]: kind: objc-instance-method | name: p1_method | {{.*}} | loc: {{.*}}hidden-redecls-sub.h:3:9 | {{.*}} | isRedecl: 1
|
Loading…
Reference in New Issue