]> granicus.if.org Git - clang/commitdiff
Fix crasher reported in PR 4209 caused by an invalid summary
authorTed Kremenek <kremenek@apple.com>
Wed, 13 May 2009 18:16:01 +0000 (18:16 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 13 May 2009 18:16:01 +0000 (18:16 +0000)
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
test/Analysis/pr4209.m [new file with mode: 0644]

index c31a8cd53d9fe8346d8dae2e5581c0f9d0f6a9ea..e00ede090b5c4d8c6ffbd6fb64bfad9652a8b60b 100644 (file)
@@ -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);
diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m
new file mode 100644 (file)
index 0000000..7d7d8fc
--- /dev/null
@@ -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)    {
+      }
+    }
+  }
+}