Skip to content

Commit fbb499e

Browse files
bnbarhamakyrtzi
authored andcommitted
[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
1 parent 8a5858c commit fbb499e

File tree

5 files changed

+37
-4
lines changed

5 files changed

+37
-4
lines changed

clang/lib/AST/DeclObjC.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,8 @@ ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {
950950
if (!Redecl && isRedeclaration()) {
951951
// This is the last redeclaration, go back to the first method.
952952
return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
953-
isInstanceMethod());
953+
isInstanceMethod(),
954+
/*AllowHidden=*/true);
954955
}
955956

956957
return Redecl ? Redecl : this;
@@ -983,7 +984,8 @@ ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
983984
if (isRedeclaration()) {
984985
// It is possible that we have not done deserializing the ObjCMethod yet.
985986
ObjCMethodDecl *MD =
986-
cast<ObjCContainerDecl>(CtxD)->getMethod(Sel, isInstanceMethod());
987+
cast<ObjCContainerDecl>(CtxD)->getMethod(Sel, isInstanceMethod(),
988+
/*AllowHidden=*/true);
987989
return MD ? MD : this;
988990
}
989991

@@ -1308,8 +1310,9 @@ void ObjCMethodDecl::getOverriddenMethods(
13081310
const ObjCMethodDecl *Method = this;
13091311

13101312
if (Method->isRedeclaration()) {
1311-
Method = cast<ObjCContainerDecl>(Method->getDeclContext())->
1312-
getMethod(Method->getSelector(), Method->isInstanceMethod());
1313+
Method = cast<ObjCContainerDecl>(Method->getDeclContext())
1314+
->getMethod(Method->getSelector(), Method->isInstanceMethod(),
1315+
/*AllowHidden=*/true);
13131316
}
13141317

13151318
if (Method->isOverriding()) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@protocol P1
2+
- (void)p1_method;
3+
- (void)p1_method;
4+
@end
5+
6+
@interface Foo (SubP1) <P1>
7+
@end
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@interface Foo
2+
- (void)parent_method;
3+
@end

clang/test/Index/Inputs/module.map

+8
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,11 @@ module PreambleWithImplicitImport {
2020
export *
2121
}
2222
}
23+
24+
module hidden_redecls {
25+
header "hidden-redecls.h"
26+
27+
explicit module sub {
28+
header "hidden-redecls-sub.h"
29+
}
30+
}

clang/test/Index/hidden-redecls.m

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@import hidden_redecls;
2+
3+
@interface Foo (Top)
4+
- (void)top_method;
5+
@end
6+
7+
// p1_method in protocol P1 is hidden since module_redecls.sub hasn't been
8+
// imported yet. Check it is still indexed.
9+
10+
// RUN: c-index-test -index-file-full %s -isystem %S/Inputs -fmodules -target x86_64-apple-macosx10.7 | FileCheck %s
11+
// CHECK: [indexDeclaration]: kind: objc-instance-method | name: p1_method | {{.*}} | loc: {{.*}}hidden-redecls-sub.h:2:9 | {{.*}} | isRedecl: 0
12+
// CHECK: [indexDeclaration]: kind: objc-instance-method | name: p1_method | {{.*}} | loc: {{.*}}hidden-redecls-sub.h:3:9 | {{.*}} | isRedecl: 1

0 commit comments

Comments
 (0)