aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-05-12 22:04:39 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-05-12 22:04:39 +0000
commit96b69a7305e20c98f1a3e2e7cd52e2d6c5d53835 (patch)
treecc4277e0b4e854f1407ecb6bdf1d5863814ab373
parentaad16096f49e670aecc92beaa49b33d1c9aba4f2 (diff)
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
-rw-r--r--include/clang/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaDeclObjC.cpp10
2 files changed, 8 insertions, 5 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 27833f562a..555060eac1 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -4739,7 +4739,8 @@ public:
void CheckForwardProtocolDeclarationForCircularDependency(
IdentifierInfo *PName,
SourceLocation &PLoc, SourceLocation PrevLoc,
- const ObjCList<ObjCProtocolDecl> &PList);
+ const ObjCList<ObjCProtocolDecl> &PList,
+ bool &err);
Decl *ActOnStartProtocolInterface(
SourceLocation AtProtoInterfaceLoc,
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 7b235bab5d..58eb0c99f2 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -275,7 +275,7 @@ Decl *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
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 @@ void Sema::CheckForwardProtocolDeclarationForCircularDependency(
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 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
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 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
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 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
}
if (AttrList)
ProcessDeclAttributeList(TUScope, PDecl, AttrList);
- if (NumProtoRefs) {
+ if (!err && NumProtoRefs ) {
/// Check then save referenced protocols.
PDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
ProtoLocs, Context);