From: Chris Lattner Date: Mon, 21 Jul 2008 04:59:05 +0000 (+0000) Subject: Fix a bunch of crashes that occur in (attempted) handling of objc properties. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a38e6b1f00d6e62d7f20a63053db6f77ab39ea36;p=clang Fix a bunch of crashes that occur in (attempted) handling of objc properties. This code would previously crash on x.y where x is 'id'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53827 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 3c5a467edc..13f7ff9fb7 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -616,7 +616,8 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, MemberLoc, MemberType); } - // Handle access to Objective C instance variables, such as "Obj->ivar". + // Handle access to Objective-C instance variables, such as "Obj->ivar" and + // (*Obj).ivar. if (const ObjCInterfaceType *IFTy = BaseType->getAsObjCInterfaceType()) { if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(&Member)) return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr, @@ -626,47 +627,39 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, BaseExpr->getSourceRange(), SourceRange(MemberLoc)); } - // Handle property access. - if (isObjCObjectPointerType(BaseType)) { - const PointerType *pointerType = BaseType->getAsPointerType(); - BaseType = pointerType->getPointeeType(); - ObjCInterfaceDecl *IFace; - QualType CanonType = BaseType.getCanonicalType(); - if (isa(CanonType)) - IFace = dyn_cast(CanonType)->getDecl(); - else - IFace = dyn_cast(CanonType)->getDecl(); - if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(&Member)) - return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr, - OpKind==tok::arrow); - // Check for properties. - if (OpKind==tok::period) { - // Before we look for explicit property declarations, we check for - // nullary methods (which allow '.' notation). - Selector Sel = PP.getSelectorTable().getNullarySelector(&Member); - ObjCMethodDecl *MD = IFace->lookupInstanceMethod(Sel); - if (MD) - return new ObjCPropertyRefExpr(MD, MD->getResultType(), - MemberLoc, BaseExpr); - // FIXME: Need to deal with setter methods that take 1 argument. E.g.: - // @interface NSBundle : NSObject {} - // - (NSString *)bundlePath; - // - (void)setBundlePath:(NSString *)x; - // @end - // void someMethod() { frameworkBundle.bundlePath = 0; } - // - ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member); - - if (!PD) { // Lastly, check protocols on qualified interfaces. - if (ObjCQualifiedInterfaceType *QIT = - dyn_cast(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); + // Handle Objective-C property access, which is "Obj.property" where Obj is a + // pointer to a (potentially qualified) interface type. + const PointerType *PTy; + const ObjCInterfaceType *IFTy; + if (OpKind == tok::period && (PTy = BaseType->getAsPointerType()) && + (IFTy = PTy->getPointeeType()->getAsObjCInterfaceType())) { + ObjCInterfaceDecl *IFace = IFTy->getDecl(); + + // Before we look for explicit property declarations, we check for + // nullary methods (which allow '.' notation). + Selector Sel = PP.getSelectorTable().getNullarySelector(&Member); + + if (ObjCMethodDecl *MD = IFace->lookupInstanceMethod(Sel)) + return new ObjCPropertyRefExpr(MD, MD->getResultType(), + MemberLoc, BaseExpr); + + // FIXME: Need to deal with setter methods that take 1 argument. E.g.: + // @interface NSBundle : NSObject {} + // - (NSString *)bundlePath; + // - (void)setBundlePath:(NSString *)x; + // @end + // void someMethod() { frameworkBundle.bundlePath = 0; } + // + if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member)) + return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc, BaseExpr); + + // Lastly, check protocols on qualified interfaces. + if (const ObjCQualifiedInterfaceType *QIT = + dyn_cast(IFTy)) { + for (unsigned i = 0; i != QIT->getNumProtocols(); ++i) + if (ObjCPropertyDecl *PD = + QIT->getProtocols(i)->FindPropertyDeclaration(&Member)) + return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc,BaseExpr); } }