зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
686226b538
Коммит
3d2c22b1d3
|
@ -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
|
Загрузка…
Ссылка в новой задаче