[cfe-commits] r52001 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/AST/DeclObjC.cpp lib/Sema/SemaExpr.cpp test/Sema/objc-props-on-prots.m

Steve Naroff snaroff at apple.com
Thu Jun 5 06:55:23 PDT 2008


Author: snaroff
Date: Thu Jun  5 08:55:23 2008
New Revision: 52001

URL: http://llvm.org/viewvc/llvm-project?rev=52001&view=rev
Log:
Fix <rdar://problem/5987482> clang on xcode: null dereference in Sema::ActOnMemberReferenceExpr.

In addition to fixing the crasher, this commit fixes further improves property lookup (by searching protocols of qualified interfaces..."NSObject <prot>").

Added:
    cfe/trunk/test/Sema/objc-props-on-prots.m
Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=52001&r1=52000&r2=52001&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Thu Jun  5 08:55:23 2008
@@ -543,6 +543,8 @@
   
   unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
   unsigned getNumClassMethods() const { return NumClassMethods; }
+
+  ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
   
   unsigned getNumPropertyDecl() const { return NumPropertyDecl; }
   

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=52001&r1=52000&r2=52001&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Thu Jun  5 08:55:23 2008
@@ -157,6 +157,14 @@
     if (property)
       return property;
   }
+  // Look through protocols.
+  for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
+       E = protocol_end(); I != E; ++I) {
+    ObjCProtocolDecl *Protocol = *I;
+    ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
+    if (property)
+      return property;
+  }
   if (getSuperClass())
     return getSuperClass()->FindPropertyDeclaration(PropertyId);
   return 0;
@@ -397,6 +405,20 @@
   return 0;
 }
 
+/// FindPropertyDeclaration - Finds declaration of the property given its name
+/// in 'PropertyId' and returns it. It returns 0, if not found.
+///
+ObjCPropertyDecl *
+ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
+  for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
+       E = classprop_end(); I != E; ++I) {
+    ObjCPropertyDecl *property = *I;
+    if (property->getIdentifier() == PropertyId)
+      return property;
+  }
+  return 0;
+}
+
 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
   IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
   ObjCInterfaceDecl* ClassDecl = this;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun  5 08:55:23 2008
@@ -602,10 +602,11 @@
     return new ExtVectorElementExpr(ret, BaseExpr, Member, MemberLoc);
   } else if (BaseType->isObjCInterfaceType()) {
     ObjCInterfaceDecl *IFace;
-    if (isa<ObjCInterfaceType>(BaseType.getCanonicalType()))
-      IFace = dyn_cast<ObjCInterfaceType>(BaseType)->getDecl();
+    QualType CanonType = BaseType.getCanonicalType();
+    if (isa<ObjCInterfaceType>(CanonType))
+      IFace = dyn_cast<ObjCInterfaceType>(CanonType)->getDecl();
     else
-      IFace = dyn_cast<ObjCQualifiedInterfaceType>(BaseType)->getDecl();
+      IFace = dyn_cast<ObjCQualifiedInterfaceType>(CanonType)->getDecl();
     ObjCInterfaceDecl *clsDeclared;
     if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(&Member, clsDeclared))
       return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr, 
@@ -614,10 +615,11 @@
     PointerType *pointerType = static_cast<PointerType*>(BaseType.getTypePtr());
     BaseType = pointerType->getPointeeType();
     ObjCInterfaceDecl *IFace;
-    if (isa<ObjCInterfaceType>(BaseType.getCanonicalType()))
-      IFace = dyn_cast<ObjCInterfaceType>(BaseType)->getDecl();
+    QualType CanonType = BaseType.getCanonicalType();
+    if (isa<ObjCInterfaceType>(CanonType))
+      IFace = dyn_cast<ObjCInterfaceType>(CanonType)->getDecl();
     else
-      IFace = dyn_cast<ObjCQualifiedInterfaceType>(BaseType)->getDecl();
+      IFace = dyn_cast<ObjCQualifiedInterfaceType>(CanonType)->getDecl();
     ObjCInterfaceDecl *clsDeclared;
     if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(&Member, clsDeclared))
       return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr, 
@@ -639,6 +641,15 @@
       // void someMethod() { frameworkBundle.bundlePath = 0; }
       //
       ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member);
+      
+      if (!PD) { // Lastly, check protocols on qualified interfaces.
+        if (ObjCQualifiedInterfaceType *QIT = 
+            dyn_cast<ObjCQualifiedInterfaceType>(CanonType)) {
+          for (unsigned i = 0; i < QIT->getNumProtocols(); i++)
+            if ((PD = QIT->getProtocols(i)->FindPropertyDeclaration(&Member)))
+              break;
+        }
+      }
       if (PD)
         return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc, BaseExpr);
     }

Added: cfe/trunk/test/Sema/objc-props-on-prots.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/objc-props-on-prots.m?rev=52001&view=auto

==============================================================================
--- cfe/trunk/test/Sema/objc-props-on-prots.m (added)
+++ cfe/trunk/test/Sema/objc-props-on-prots.m Thu Jun  5 08:55:23 2008
@@ -0,0 +1,65 @@
+// RUN: clang -fsyntax-only -verify %s
+typedef signed char BOOL;
+ at class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
+
+ at protocol NSObject
+- (BOOL) isEqual:(id) object;
+ at end
+
+ at protocol NSCoding
+- (void) encodeWithCoder:(NSCoder *) aCoder;
+ at end
+
+ at interface NSObject < NSObject > {} @end
+
+typedef float CGFloat;
+
+ at interface NSResponder:NSObject < NSCoding > {} @end
+
+ at class XCElementView;
+
+typedef struct _XCElementInset {} XCElementInset;
+
+ at protocol XCElementP < NSObject >
+-(BOOL) vertical;
+ at end
+
+ at protocol XCElementDisplayDelegateP;
+ at protocol XCElementTabMarkerP;
+
+typedef NSObject < XCElementTabMarkerP > XCElementTabMarker;
+
+ at protocol XCElementTabberP < XCElementP >
+-(void) setMarker:(XCElementTabMarker *) marker;
+ at end
+
+typedef NSObject < XCElementTabberP > XCElementTabber;
+
+ at protocol XCElementTabMarkerP < NSObject >
+ at property(nonatomic)
+BOOL variableSized;
+ at end
+
+ at protocol XCElementJustifierP < XCElementP >
+-(void) setHJustification:(CGFloat) hJust;
+ at end
+
+typedef NSObject < XCElementJustifierP > XCElementJustifier;
+ at interface XCElementImp:NSObject < XCElementP > {}
+ at end
+
+ at class XCElementImp;
+
+ at interface XCElementTabberImp:XCElementImp < XCElementTabberP > {
+	XCElementTabMarker *_marker;
+}
+ at end
+
+ at implementation XCElementTabberImp 
+- (void) setMarker:(XCElementTabMarker *) marker {
+  if (_marker && _marker.variableSized) {
+  }
+}
+- vertical { return self; }
+- (BOOL)isEqual:x { return 1; }
+ at end





More information about the cfe-commits mailing list