]> granicus.if.org Git - clang/commitdiff
More Sema check for ivars in class continuation.
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 23 Feb 2010 23:41:11 +0000 (23:41 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 23 Feb 2010 23:41:11 +0000 (23:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97002 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclObjC.cpp
test/SemaObjC/duplicate-ivar-in-class-extension.m [new file with mode: 0644]

index 4ea379328c1776b4160535a209ab2a449e96af58..2190e3b5bfab675b1030ec325f3ffaa814ca5264 100644 (file)
@@ -1440,6 +1440,8 @@ public:
   void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl,
                                        ObjCContainerDecl* IDecl);
 
+  void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
+
   /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
   /// true, or false, accordingly.
   bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
index 0be3841ad5a8ad9b35b2e429a31e7faa3c8356a7..27eb2510ec5504efd966aabf8587d545e155a828 100644 (file)
@@ -5659,21 +5659,8 @@ void Sema::ActOnFields(Scope* S,
       }
       // Must enforce the rule that ivars in the base classes may not be
       // duplicates.
-      if (ID->getSuperClass()) {
-        for (ObjCInterfaceDecl::ivar_iterator IVI = ID->ivar_begin(),
-             IVE = ID->ivar_end(); IVI != IVE; ++IVI) {
-          ObjCIvarDecl* Ivar = (*IVI);
-
-          if (IdentifierInfo *II = Ivar->getIdentifier()) {
-            ObjCIvarDecl* prevIvar =
-              ID->getSuperClass()->lookupInstanceVariable(II);
-            if (prevIvar) {
-              Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
-              Diag(prevIvar->getLocation(), diag::note_previous_declaration);
-            }
-          }
-        }
-      }
+      if (ID->getSuperClass())
+        DiagnoseDuplicateIvars(ID, ID->getSuperClass());
     } else if (ObjCImplementationDecl *IMPDecl =
                   dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
       assert(IMPDecl && "ActOnFields - missing ObjCImplementationDecl");
index 925c0db4e40da4544a46654488d0542e10dea40c..939ccab35db7cb585fe8b2c0199e46da493334f9 100644 (file)
@@ -1781,6 +1781,29 @@ void Sema::CompareMethodParamsInBaseAndSuper(Decl *ClassDecl,
   }
 }
 
+/// DiagnoseDuplicateIvars - 
+/// Check for duplicate ivars in the entire class at the start of 
+/// @implementation. This becomes necesssary because class extension can
+/// add ivars to a class in random order which will not be known until
+/// class's @implementation is seen.
+void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, 
+                                  ObjCInterfaceDecl *SID) {
+  for (ObjCInterfaceDecl::ivar_iterator IVI = ID->ivar_begin(),
+       IVE = ID->ivar_end(); IVI != IVE; ++IVI) {
+    ObjCIvarDecl* Ivar = (*IVI);
+    if (Ivar->isInvalidDecl())
+      continue;
+    if (IdentifierInfo *II = Ivar->getIdentifier()) {
+      ObjCIvarDecl* prevIvar = SID->lookupInstanceVariable(II);
+      if (prevIvar) {
+        Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
+        Diag(prevIvar->getLocation(), diag::note_previous_declaration);
+        Ivar->setInvalidDecl();
+      }
+    }
+  }
+}
+
 // Note: For class/category implemenations, allMethods/allProperties is
 // always null.
 void Sema::ActOnAtEnd(SourceRange AtEnd,
@@ -1892,6 +1915,11 @@ void Sema::ActOnAtEnd(SourceRange AtEnd,
     if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
       ImplMethodsVsClassMethods(IC, IDecl);
       AtomicPropertySetterGetterRules(IC, IDecl);
+      if (LangOpts.ObjCNonFragileABI2)
+        while (IDecl->getSuperClass()) {
+          DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
+          IDecl = IDecl->getSuperClass();
+        }
     }
   } else if (ObjCCategoryImplDecl* CatImplClass =
                                    dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
diff --git a/test/SemaObjC/duplicate-ivar-in-class-extension.m b/test/SemaObjC/duplicate-ivar-in-class-extension.m
new file mode 100644 (file)
index 0000000..b66736f
--- /dev/null
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+@interface Root @end
+
+@interface SuperClass  : Root 
+{
+  int iSuper;  // expected-note {{previous declaration is here}}
+}
+@end
+
+@interface SubClass : SuperClass {
+    int ivar;  // expected-error {{duplicate member 'ivar'}}
+    int another_ivar;  // expected-error {{duplicate member 'another_ivar'}}
+    int iSuper;        // expected-error {{duplicate member 'iSuper'}}
+}
+@end
+
+@interface SuperClass () {
+   int ivar;   // expected-note {{previous declaration is here}}
+}
+@end
+
+@interface Root () {
+  int another_ivar;    // expected-note {{previous declaration is here}}
+}
+@end
+
+@implementation SubClass
+-(int) method {
+        return self->ivar;  // would be ambiguous if the duplicate ivar were allowed
+}
+@end