[cfe-commits] r75178 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclObjC.cpp test/SemaObjC/undef-superclass-1.m

Fariborz Jahanian fjahanian at apple.com
Thu Jul 9 15:08:26 PDT 2009


Author: fjahanian
Date: Thu Jul  9 17:08:26 2009
New Revision: 75178

URL: http://llvm.org/viewvc/llvm-project?rev=75178&view=rev
Log:
don't crash if class is using itself as its super class.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/test/SemaObjC/undef-superclass-1.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=75178&r1=75177&r2=75178&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jul  9 17:08:26 2009
@@ -145,6 +145,8 @@
   "duplicate interface definition for class %0">;
 def err_undef_superclass : Error<
   "cannot find interface declaration for %0, superclass of %1">;
+def err_recursive_superclass : Error<
+  "trying to recursively use %0 as superclass of %1">;
 def warn_previous_alias_decl : Warning<"previously declared alias is ignored">;
 def err_conflicting_aliasing_type : Error<"conflicting types for alias %0">;
 def warn_undef_interface : Warning<"cannot find interface declaration for %0">;

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=75178&r1=75177&r2=75178&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Jul  9 17:08:26 2009
@@ -124,48 +124,54 @@
   if (SuperName) {
     // Check if a different kind of symbol declared in this scope.
     PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName);
+    if (PrevDecl == IDecl) {
+      Diag(SuperLoc, diag::err_recursive_superclass)
+        << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
+      IDecl->setLocEnd(ClassLoc);
+    }
+    else {
+      ObjCInterfaceDecl *SuperClassDecl = 
+                                dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
 
-    ObjCInterfaceDecl *SuperClassDecl = 
-                                  dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
-
-    // Diagnose classes that inherit from deprecated classes.
-    if (SuperClassDecl)
-      (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
-    
-    if (PrevDecl && SuperClassDecl == 0) {
-      // The previous declaration was not a class decl. Check if we have a
-      // typedef. If we do, get the underlying class type.
-      if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
-        QualType T = TDecl->getUnderlyingType();
-        if (T->isObjCInterfaceType()) {
-          if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl())
-            SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
+      // Diagnose classes that inherit from deprecated classes.
+      if (SuperClassDecl)
+        (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
+    
+      if (PrevDecl && SuperClassDecl == 0) {
+        // The previous declaration was not a class decl. Check if we have a
+        // typedef. If we do, get the underlying class type.
+        if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
+          QualType T = TDecl->getUnderlyingType();
+          if (T->isObjCInterfaceType()) {
+            if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl())
+              SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
+          }
         }
-      }
       
-      // This handles the following case:
-      //
-      // typedef int SuperClass;
-      // @interface MyClass : SuperClass {} @end
-      //
-      if (!SuperClassDecl) {
-        Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
-        Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+        // This handles the following case:
+        //
+        // typedef int SuperClass;
+        // @interface MyClass : SuperClass {} @end
+        //
+        if (!SuperClassDecl) {
+          Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
+          Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+        }
       }
+  
+      if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
+        if (!SuperClassDecl)
+          Diag(SuperLoc, diag::err_undef_superclass)
+            << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
+        else if (SuperClassDecl->isForwardDecl())
+          Diag(SuperLoc, diag::err_undef_superclass)
+            << SuperClassDecl->getDeclName() << ClassName
+            << SourceRange(AtInterfaceLoc, ClassLoc);
+      }
+      IDecl->setSuperClass(SuperClassDecl);
+      IDecl->setSuperClassLoc(SuperLoc);
+      IDecl->setLocEnd(SuperLoc);
     }
-    
-    if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
-      if (!SuperClassDecl)
-        Diag(SuperLoc, diag::err_undef_superclass)
-          << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
-      else if (SuperClassDecl->isForwardDecl())
-        Diag(SuperLoc, diag::err_undef_superclass)
-          << SuperClassDecl->getDeclName() << ClassName
-          << SourceRange(AtInterfaceLoc, ClassLoc);
-    }
-    IDecl->setSuperClass(SuperClassDecl);
-    IDecl->setSuperClassLoc(SuperLoc);
-    IDecl->setLocEnd(SuperLoc);
   } else { // we have a root class.
     IDecl->setLocEnd(ClassLoc);
   }

Modified: cfe/trunk/test/SemaObjC/undef-superclass-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/undef-superclass-1.m?rev=75178&r1=75177&r2=75178&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/undef-superclass-1.m (original)
+++ cfe/trunk/test/SemaObjC/undef-superclass-1.m Thu Jul  9 17:08:26 2009
@@ -24,3 +24,10 @@
     [super dealloc]; // expected-error {{no super class declared in @interface for 'SUPER'}}
 }
 @end
+
+ at interface RecursiveClass : RecursiveClass // expected-error {{trying to recursively use 'RecursiveClass' as superclass of 'RecursiveClass'}}
+ at end
+
+ at implementation RecursiveClass
+ at end
+





More information about the cfe-commits mailing list