From 70b6a83b833c40f320d0ed2310cbcdf2be4cece0 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 13 May 2009 18:16:01 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71685 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/CFRefCount.cpp | 20 ++++++++--- test/Analysis/pr4209.m | 70 +++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 test/Analysis/pr4209.m diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index c31a8cd53d..e00ede090b 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -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& 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& 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); diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m new file mode 100644 index 0000000000..7d7d8fc5a1 --- /dev/null +++ b/test/Analysis/pr4209.m @@ -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 { +} +@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 - (NSUInteger)count; +@end @interface NSMutableArray : NSArray - (void)addObject:(id)anObject; +@end typedef unsigned short unichar; +@interface NSString : NSObject - (NSUInteger)length; +- (int)intValue; +@end @interface NSSimpleCString : NSString { +} +@end @interface NSConstantString : NSSimpleCString @end extern void *_NSConstantStringClassReference; +@interface NSDictionary : NSObject - (NSUInteger)count; +@end @interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; +@end typedef struct { +} +CMProfileLocation; +@interface NSResponder : NSObject { +} +@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView; +@interface NSCell : NSObject { +} +@end extern NSString *NSControlTintDidChangeNotification; +@interface NSActionCell : NSCell { +} +@end @class NSArray, NSDocument, NSWindow; +@interface NSWindowController : NSResponder { +} +@end @class EBayCategoryType, GSEbayCategory, GBSearchRequest; +@interface GBCategoryChooserPanelController : NSWindowController { + GSEbayCategory *rootCategory; +} +- (NSMutableDictionary*)categoryDictionaryForCategoryID:(int)inID inRootTreeCategories:(NSMutableArray*)inRootTreeCategories; +-(NSString*) categoryID; +@end @interface GSEbayCategory : NSObject { +} +- (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) { + } + } + } +} -- 2.40.0