Skip to content

Commit 5f8b909

Browse files
committed
[ODRHash] Fix null pointer dereference for ObjC selectors with empty slots.
`Selector::getIdentifierInfoForSlot` returns NULL if a slot has no corresponding identifier. Add a boolean to the hash and a NULL check. rdar://problem/51615164 Reviewers: rtrieu Reviewed By: rtrieu Subscribers: dexonsmith, cfe-commits, jkorous Differential Revision: https://reviews.llvm.org/D63789 llvm-svn: 364664
1 parent 021d2f2 commit 5f8b909

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

clang/lib/AST/ODRHash.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,13 @@ void ODRHash::AddDeclarationNameImpl(DeclarationName Name) {
7171
AddBoolean(S.isKeywordSelector());
7272
AddBoolean(S.isUnarySelector());
7373
unsigned NumArgs = S.getNumArgs();
74+
ID.AddInteger(NumArgs);
7475
for (unsigned i = 0; i < NumArgs; ++i) {
75-
AddIdentifierInfo(S.getIdentifierInfoForSlot(i));
76+
const IdentifierInfo *II = S.getIdentifierInfoForSlot(i);
77+
AddBoolean(II);
78+
if (II) {
79+
AddIdentifierInfo(II);
80+
}
7681
}
7782
break;
7883
}

clang/test/Modules/odr_hash.mm

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ @interface Interface2 <T : I1 *>
5757
@interface Interface3 <T : I1 *>
5858
@end
5959

60+
@interface EmptySelectorSlot
61+
- (void)method:(int)arg;
62+
- (void)method:(int)arg :(int)empty;
63+
64+
- (void)multiple:(int)arg1 args:(int)arg2 :(int)arg3;
65+
- (void)multiple:(int)arg1 :(int)arg2 args:(int)arg3;
66+
@end
67+
6068
#endif
6169

6270
#if defined(FIRST)
@@ -289,6 +297,29 @@ @interface Interface6 <T1 : I1 *, T2 : I2 *> {
289297
} // namespace ObjCTypeParam
290298
} // namespace Types
291299

300+
namespace CallMethods {
301+
#if defined(FIRST)
302+
void invalid1(EmptySelectorSlot *obj) {
303+
[obj method:0];
304+
}
305+
void invalid2(EmptySelectorSlot *obj) {
306+
[obj multiple:0 args:0 :0];
307+
}
308+
#elif defined(SECOND)
309+
void invalid1(EmptySelectorSlot *obj) {
310+
[obj method:0 :0];
311+
}
312+
void invalid2(EmptySelectorSlot *obj) {
313+
[obj multiple:0 :0 args:0];
314+
}
315+
#endif
316+
// [email protected]:* {{'CallMethods::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}
317+
// [email protected]:* {{but in 'FirstModule' found a different body}}
318+
319+
// [email protected]:* {{'CallMethods::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}
320+
// [email protected]:* {{but in 'FirstModule' found a different body}}
321+
} // namespace CallMethods
322+
292323
// Keep macros contained to one file.
293324
#ifdef FIRST
294325
#undef FIRST

0 commit comments

Comments
 (0)