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>").


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52001 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Steve Naroff 2008-06-05 13:55:23 +00:00
Родитель 686226b538
Коммит 3d2c22b1d3
4 изменённых файлов: 106 добавлений и 6 удалений

Просмотреть файл

@ -543,6 +543,8 @@ public:
unsigned getNumInstanceMethods() const { return NumInstanceMethods; }
unsigned getNumClassMethods() const { return NumClassMethods; }
ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
unsigned getNumPropertyDecl() const { return NumPropertyDecl; }

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);
}

Просмотреть файл

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