diff options
| author | Steve Naroff <snaroff@apple.com> | 2008-06-05 13:55:23 +0000 |
|---|---|---|
| committer | Steve Naroff <snaroff@apple.com> | 2008-06-05 13:55:23 +0000 |
| commit | f9c65246dd3512d381f9f052b8b7be9459eef063 (patch) | |
| tree | 80bd2d676b4e91b511a83f1c03d27f070e1bce5d /clang/lib | |
| parent | 3f8de8b130740282b97a2ca632f94b1b371789c0 (diff) | |
| download | bcm5719-llvm-f9c65246dd3512d381f9f052b8b7be9459eef063.tar.gz bcm5719-llvm-f9c65246dd3512d381f9f052b8b7be9459eef063.zip | |
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>").
llvm-svn: 52001
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 22 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 23 |
2 files changed, 39 insertions, 6 deletions
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index e493d27ac33..6536df6e1e1 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -157,6 +157,14 @@ ObjCPropertyDecl * 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 @@ ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { 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; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8d382485b1d..89609501ff8 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -602,10 +602,11 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, 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 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, 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 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, // 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); } |

