Fix crasher reported in PR 4209 caused by an invalid summary
generation when EvalObjCMessageExpr() did not resolve the ObjCInterfaceDecl* for a receiver when the receiver's symbolic value wasn't being explicitly tracked. llvm-svn: 71685
This commit is contained in:
parent
027b886a99
commit
5801f65a52
|
@ -439,6 +439,9 @@ public:
|
|||
|
||||
ObjCSummaryKey(const ObjCInterfaceDecl* d, Selector s)
|
||||
: II(d ? d->getIdentifier() : 0), S(s) {}
|
||||
|
||||
ObjCSummaryKey(const ObjCInterfaceDecl* d, IdentifierInfo *ii, Selector s)
|
||||
: II(d ? d->getIdentifier() : ii), S(s) {}
|
||||
|
||||
ObjCSummaryKey(Selector s)
|
||||
: II(0), S(s) {}
|
||||
|
@ -1265,7 +1268,7 @@ RetainSummaryManager::getInstanceMethodSummary(Selector S,
|
|||
updateSummaryFromAnnotations(*Summ, MD);
|
||||
|
||||
// Memoize the summary.
|
||||
ObjCMethodSummaries[ObjCSummaryKey(ClsName, S)] = Summ;
|
||||
ObjCMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
|
||||
return Summ;
|
||||
}
|
||||
|
||||
|
@ -1288,7 +1291,7 @@ RetainSummaryManager::getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
|
|||
updateSummaryFromAnnotations(*Summ, MD);
|
||||
|
||||
// Memoize the summary.
|
||||
ObjCClassMethodSummaries[ObjCSummaryKey(ClsName, S)] = Summ;
|
||||
ObjCClassMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
|
||||
return Summ;
|
||||
}
|
||||
|
||||
|
@ -2926,7 +2929,7 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
|
|||
if (Expr* Receiver = ME->getReceiver()) {
|
||||
// We need the type-information of the tracked receiver object
|
||||
// Retrieve it from the state.
|
||||
ObjCInterfaceDecl* ID = 0;
|
||||
const ObjCInterfaceDecl* ID = 0;
|
||||
|
||||
// FIXME: Wouldn't it be great if this code could be reduced? It's just
|
||||
// a chain of lookups.
|
||||
|
@ -2948,7 +2951,16 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// FIXME: this is a hack. This may or may not be the actual method
|
||||
// that is called.
|
||||
if (!ID) {
|
||||
if (const PointerType *PT = Receiver->getType()->getAsPointerType())
|
||||
if (const ObjCInterfaceType *p =
|
||||
PT->getPointeeType()->getAsObjCInterfaceType())
|
||||
ID = p->getDecl();
|
||||
}
|
||||
|
||||
// FIXME: The receiver could be a reference to a class, meaning that
|
||||
// we should use the class method.
|
||||
Summ = Summaries.getInstanceMethodSummary(ME, ID);
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -verify %s &&
|
||||
// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref -analyzer-store=region -verify %s
|
||||
|
||||
// This test case was crashing due to how CFRefCount.cpp resolved the
|
||||
// ObjCInterfaceDecl* and ClassName in EvalObjCMessageExpr.
|
||||
|
||||
typedef signed char BOOL;
|
||||
typedef unsigned int NSUInteger;
|
||||
typedef struct _NSZone NSZone;
|
||||
@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
|
||||
@protocol NSObject - (BOOL)isEqual:(id)object;
|
||||
@end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone;
|
||||
@end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone;
|
||||
@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
|
||||
@end @interface NSObject <NSObject> {
|
||||
}
|
||||
@end typedef float CGFloat;
|
||||
typedef struct _NSPoint {
|
||||
}
|
||||
NSFastEnumerationState;
|
||||
@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
|
||||
@end @class NSString;
|
||||
@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
|
||||
@end @interface NSMutableArray : NSArray - (void)addObject:(id)anObject;
|
||||
@end typedef unsigned short unichar;
|
||||
@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length;
|
||||
- (int)intValue;
|
||||
@end @interface NSSimpleCString : NSString {
|
||||
}
|
||||
@end @interface NSConstantString : NSSimpleCString @end extern void *_NSConstantStringClassReference;
|
||||
@interface NSDictionary : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count;
|
||||
@end @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey;
|
||||
@end typedef struct {
|
||||
}
|
||||
CMProfileLocation;
|
||||
@interface NSResponder : NSObject <NSCoding> {
|
||||
}
|
||||
@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView;
|
||||
@interface NSCell : NSObject <NSCopying, NSCoding> {
|
||||
}
|
||||
@end extern NSString *NSControlTintDidChangeNotification;
|
||||
@interface NSActionCell : NSCell {
|
||||
}
|
||||
@end @class NSArray, NSDocument, NSWindow;
|
||||
@interface NSWindowController : NSResponder <NSCoding> {
|
||||
}
|
||||
@end @class EBayCategoryType, GSEbayCategory, GBSearchRequest;
|
||||
@interface GBCategoryChooserPanelController : NSWindowController {
|
||||
GSEbayCategory *rootCategory;
|
||||
}
|
||||
- (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories;
|
||||
-(NSString*) categoryID;
|
||||
@end @interface GSEbayCategory : NSObject <NSCoding> {
|
||||
}
|
||||
- (int) categoryID;
|
||||
- (GSEbayCategory *) parent;
|
||||
- (GSEbayCategory*) subcategoryWithID:(int) inID;
|
||||
@end @implementation GBCategoryChooserPanelController + (int) chooseCategoryIDFromCategories:(NSArray*) inCategories searchRequest:(GBSearchRequest*)inRequest parentWindow:(NSWindow*) inParent {
|
||||
}
|
||||
- (void) addCategory:(EBayCategoryType*)inCategory toRootTreeCategory:(NSMutableArray*)inRootTreeCategories {
|
||||
GSEbayCategory *category = [rootCategory subcategoryWithID:[[inCategory categoryID] intValue]];
|
||||
if (rootCategory != category) {
|
||||
GSEbayCategory *parent = category;
|
||||
while ((((void*)0) != (parent = [parent parent])) && ([parent categoryID] != 0)) {
|
||||
NSMutableDictionary *treeCategoryDict = [self categoryDictionaryForCategoryID:[parent categoryID] inRootTreeCategories:inRootTreeCategories];
|
||||
if (((void*)0) == treeCategoryDict) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue