[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
This commit is contained in:
Volodymyr Sapsai 2019-06-28 17:42:17 +00:00
parent 021d2f2093
commit 5f8b9092ff
2 changed files with 37 additions and 1 deletions

View File

@ -71,8 +71,13 @@ void ODRHash::AddDeclarationNameImpl(DeclarationName Name) {
AddBoolean(S.isKeywordSelector());
AddBoolean(S.isUnarySelector());
unsigned NumArgs = S.getNumArgs();
ID.AddInteger(NumArgs);
for (unsigned i = 0; i < NumArgs; ++i) {
AddIdentifierInfo(S.getIdentifierInfoForSlot(i));
const IdentifierInfo *II = S.getIdentifierInfoForSlot(i);
AddBoolean(II);
if (II) {
AddIdentifierInfo(II);
}
}
break;
}

View File

@ -57,6 +57,14 @@
@interface Interface3 <T : I1 *>
@end
@interface EmptySelectorSlot
- (void)method:(int)arg;
- (void)method:(int)arg :(int)empty;
- (void)multiple:(int)arg1 args:(int)arg2 :(int)arg3;
- (void)multiple:(int)arg1 :(int)arg2 args:(int)arg3;
@end
#endif
#if defined(FIRST)
@ -289,6 +297,29 @@ Invalid3 i3;
} // namespace ObjCTypeParam
} // namespace Types
namespace CallMethods {
#if defined(FIRST)
void invalid1(EmptySelectorSlot *obj) {
[obj method:0];
}
void invalid2(EmptySelectorSlot *obj) {
[obj multiple:0 args:0 :0];
}
#elif defined(SECOND)
void invalid1(EmptySelectorSlot *obj) {
[obj method:0 :0];
}
void invalid2(EmptySelectorSlot *obj) {
[obj multiple:0 :0 args:0];
}
#endif
// expected-error@second.h:* {{'CallMethods::invalid1' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}
// expected-note@first.h:* {{but in 'FirstModule' found a different body}}
// expected-error@second.h:* {{'CallMethods::invalid2' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}
// expected-note@first.h:* {{but in 'FirstModule' found a different body}}
} // namespace CallMethods
// Keep macros contained to one file.
#ifdef FIRST
#undef FIRST