]> granicus.if.org Git - clang/commitdiff
After issuing diagnostics on circular protocol list,
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 12 May 2011 22:04:39 +0000 (22:04 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 12 May 2011 22:04:39 +0000 (22:04 +0000)
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

include/clang/Sema/Sema.h
lib/Sema/SemaDeclObjC.cpp

index 27833f562a5e89e2ac2c607ea7e624cdb180bf0c..555060eac171522311223a24874d0151771cf2af 100644 (file)
@@ -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,
index 7b235bab5d9afdb3e11f27ce10ab4bbf428c65d9..58eb0c99f2a21c1216b91e7cacde8af3f196df1e 100644 (file)
@@ -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);