After issuing diagnostics on circular protocol list,
don't build circular AST in protocol's protocol list
when user code has introduced it. Indexer and other
clients may crash. // rdar://9221614
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131254 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 7b235ba..58eb0c9 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -275,7 +275,7 @@
void Sema::CheckForwardProtocolDeclarationForCircularDependency(
IdentifierInfo *PName,
SourceLocation &Ploc, SourceLocation PrevLoc,
- const ObjCList<ObjCProtocolDecl> &PList) {
+ const ObjCList<ObjCProtocolDecl> &PList, bool &err) {
for (ObjCList<ObjCProtocolDecl>::iterator I = PList.begin(),
E = PList.end(); I != E; ++I) {
@@ -284,9 +284,10 @@
if (PDecl->getIdentifier() == PName) {
Diag(Ploc, diag::err_protocol_has_circular_dependency);
Diag(PrevLoc, diag::note_previous_definition);
+ err = true;
}
CheckForwardProtocolDeclarationForCircularDependency(PName, Ploc,
- PDecl->getLocation(), PDecl->getReferencedProtocols());
+ PDecl->getLocation(), PDecl->getReferencedProtocols(), err);
}
}
}
@@ -300,6 +301,7 @@
const SourceLocation *ProtoLocs,
SourceLocation EndProtoLoc,
AttributeList *AttrList) {
+ bool err = false;
// FIXME: Deal with AttrList.
assert(ProtocolName && "Missing protocol identifier");
ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolName, ProtocolLoc);
@@ -315,7 +317,7 @@
ObjCList<ObjCProtocolDecl> PList;
PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
CheckForwardProtocolDeclarationForCircularDependency(
- ProtocolName, ProtocolLoc, PDecl->getLocation(), PList);
+ ProtocolName, ProtocolLoc, PDecl->getLocation(), PList, err);
// Make sure the cached decl gets a valid start location.
PDecl->setLocation(AtProtoInterfaceLoc);
@@ -331,7 +333,7 @@
}
if (AttrList)
ProcessDeclAttributeList(TUScope, PDecl, AttrList);
- if (NumProtoRefs) {
+ if (!err && NumProtoRefs ) {
/// Check then save referenced protocols.
PDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
ProtoLocs, Context);