[index] Fix issue with protocol name locations in conformance list of an ObjC class when they come from a typedef.
The ObjC class protocol list assumes there is an associated location for each protocol but no location is provided when the protocol list comes from a typedef, and we end up with a buffer overflow when trying to get locations for the protocol names. Fixes crash of rdar://28980278. llvm-svn: 286331
This commit is contained in:
parent
0f1ddfa846
commit
f95a000421
|
@ -7470,6 +7470,7 @@ public:
|
|||
SourceRange SuperTypeArgsRange);
|
||||
|
||||
void ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,
|
||||
SmallVectorImpl<SourceLocation> &ProtocolLocs,
|
||||
IdentifierInfo *SuperName,
|
||||
SourceLocation SuperLoc);
|
||||
|
||||
|
|
|
@ -369,7 +369,8 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
|
|||
}
|
||||
|
||||
if (Tok.isNot(tok::less))
|
||||
Actions.ActOnTypedefedProtocols(protocols, superClassId, superClassLoc);
|
||||
Actions.ActOnTypedefedProtocols(protocols, protocolLocs,
|
||||
superClassId, superClassLoc);
|
||||
|
||||
Decl *ClsType =
|
||||
Actions.ActOnStartClassInterface(getCurScope(), AtLoc, nameId, nameLoc,
|
||||
|
|
|
@ -1028,6 +1028,7 @@ ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc,
|
|||
/// typedef'ed use for a qualified super class and adds them to the list
|
||||
/// of the protocols.
|
||||
void Sema::ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,
|
||||
SmallVectorImpl<SourceLocation> &ProtocolLocs,
|
||||
IdentifierInfo *SuperName,
|
||||
SourceLocation SuperLoc) {
|
||||
if (!SuperName)
|
||||
|
@ -1040,8 +1041,14 @@ void Sema::ActOnTypedefedProtocols(SmallVectorImpl<Decl *> &ProtocolRefs,
|
|||
if (const TypedefNameDecl *TDecl = dyn_cast_or_null<TypedefNameDecl>(IDecl)) {
|
||||
QualType T = TDecl->getUnderlyingType();
|
||||
if (T->isObjCObjectType())
|
||||
if (const ObjCObjectType *OPT = T->getAs<ObjCObjectType>())
|
||||
if (const ObjCObjectType *OPT = T->getAs<ObjCObjectType>()) {
|
||||
ProtocolRefs.append(OPT->qual_begin(), OPT->qual_end());
|
||||
// FIXME: Consider whether this should be an invalid loc since the loc
|
||||
// is not actually pointing to a protocol name reference but to the
|
||||
// typedef reference. Note that the base class name loc is also pointing
|
||||
// at the typedef.
|
||||
ProtocolLocs.append(OPT->getNumProtocols(), SuperLoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -129,3 +129,23 @@ extern int setjmp(jmp_buf);
|
|||
// CHECK: [[@LINE+1]]:12 | extension/ObjC | <no-name> | <no-usr> | <no-cgname> | Decl | rel: 0
|
||||
@interface NonExistent()
|
||||
@end
|
||||
|
||||
@interface MyGenCls<ObjectType> : Base
|
||||
@end
|
||||
|
||||
@protocol MyEnumerating
|
||||
@end
|
||||
|
||||
// CHECK: [[@LINE+4]]:41 | type-alias/C | MyEnumerator | c:index-source.m@T@MyEnumerator | <no-cgname> | Def | rel: 0
|
||||
// CHECK: [[@LINE+3]]:26 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref | rel: 0
|
||||
// CHECK: [[@LINE+2]]:9 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref | rel: 0
|
||||
// CHECK: [[@LINE+1]]:18 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref | rel: 0
|
||||
typedef MyGenCls<Base *><MyEnumerating> MyEnumerator;
|
||||
|
||||
// CHECK: [[@LINE+5]]:12 | class/ObjC | PermanentEnumerator | c:objc(cs)PermanentEnumerator | _OBJC_CLASS_$_PermanentEnumerator | Decl | rel: 0
|
||||
// CHECK: [[@LINE+4]]:34 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref,RelBase | rel: 1
|
||||
// CHECK-NEXT: RelBase | PermanentEnumerator | c:objc(cs)PermanentEnumerator
|
||||
// CHECK: [[@LINE+2]]:34 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,RelBase | rel: 1
|
||||
// CHECK-NEXT: RelBase | PermanentEnumerator | c:objc(cs)PermanentEnumerator
|
||||
@interface PermanentEnumerator : MyEnumerator
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue