r182951 - Fix potential infinite loop when iterating over redeclarations of an ObjMethodDecl, resulting from invalid code.

Argyrios Kyrtzidis akyrtzi at gmail.com
Thu May 30 11:53:21 PDT 2013


Author: akirtzidis
Date: Thu May 30 13:53:21 2013
New Revision: 182951

URL: http://llvm.org/viewvc/llvm-project?rev=182951&view=rev
Log:
Fix potential infinite loop when iterating over redeclarations of an ObjMethodDecl, resulting from invalid code.

Check for invalid decls in ObjCMethodDecl::getNextRedeclaration(); otherwise if we start from an invalid redeclaration
of an @implementation we would move to the @interface and not reach the original declaration again.

Fixes rdar://14024851

Modified:
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/test/Sema/warn-documentation.m

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=182951&r1=182950&r2=182951&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Thu May 30 13:53:21 2013
@@ -627,23 +627,29 @@ ObjCMethodDecl *ObjCMethodDecl::getNextR
 
   Decl *CtxD = cast<Decl>(getDeclContext());
 
-  if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
-    if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
-      Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
-
-  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
-    if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
-      Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
-
-  } else if (ObjCImplementationDecl *ImplD =
-               dyn_cast<ObjCImplementationDecl>(CtxD)) {
-    if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
-      Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
-
-  } else if (ObjCCategoryImplDecl *CImplD =
-               dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
-    if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
-      Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
+  if (!CtxD->isInvalidDecl()) {
+    if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) {
+      if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD))
+        if (!ImplD->isInvalidDecl())
+          Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
+
+    } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) {
+      if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD))
+        if (!ImplD->isInvalidDecl())
+          Redecl = ImplD->getMethod(getSelector(), isInstanceMethod());
+
+    } else if (ObjCImplementationDecl *ImplD =
+                 dyn_cast<ObjCImplementationDecl>(CtxD)) {
+      if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
+        if (!IFD->isInvalidDecl())
+          Redecl = IFD->getMethod(getSelector(), isInstanceMethod());
+
+    } else if (ObjCCategoryImplDecl *CImplD =
+                 dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
+      if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
+        if (!CatD->isInvalidDecl())
+          Redecl = CatD->getMethod(getSelector(), isInstanceMethod());
+    }
   }
 
   if (!Redecl && isRedeclaration()) {

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=182951&r1=182950&r2=182951&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu May 30 13:53:21 2013
@@ -935,6 +935,7 @@ Decl *Sema::ActOnStartCategoryImplementa
         << CatName;
       Diag(CatIDecl->getImplementation()->getLocation(),
            diag::note_previous_definition);
+      CDecl->setInvalidDecl();
     } else {
       CatIDecl->setImplementation(CDecl);
       // Warn on implementating category of deprecated class under 
@@ -1056,6 +1057,7 @@ Decl *Sema::ActOnStartClassImplementatio
     Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
     Diag(IDecl->getImplementation()->getLocation(),
          diag::note_previous_definition);
+    IMPDecl->setInvalidDecl();
   } else { // add it to the list.
     IDecl->setImplementation(IMPDecl);
     PushOnScopeChains(IMPDecl, TUScope);

Modified: cfe/trunk/test/Sema/warn-documentation.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-documentation.m?rev=182951&r1=182950&r2=182951&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-documentation.m (original)
+++ cfe/trunk/test/Sema/warn-documentation.m Thu May 30 13:53:21 2013
@@ -203,3 +203,15 @@ int FooBar();
 @interface Asset : NSObject
 @end
 
+// rdar://14024851 Check that this does not enter an infinite loop
+ at interface rdar14024851
+-(void)meth; // expected-note {{declared here}}
+ at end
+
+ at implementation rdar14024851 // expected-warning {{method definition for 'meth' not found}} expected-note {{previous definition}}
+ at end
+
+ at implementation rdar14024851 // expected-error {{reimplementation}}
+/// \brief comment
+-(void)meth {}
+ at end





More information about the cfe-commits mailing list