From: Ted Kremenek Date: Fri, 15 May 2009 15:49:00 +0000 (+0000) Subject: Fix crash when deriving the enclosing summary of a method whose first selector slot... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7db16041263f39df6deb1145b5c039dfd8da6af0;p=clang Fix crash when deriving the enclosing summary of a method whose first selector slot has a null IdentifierInfo*. This happens when analyzing Growl. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71857 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 67b364496b..215be47086 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -76,7 +76,14 @@ static inline const char* parseWord(const char* s) { return s; } -static NamingConvention deriveNamingConvention(const char* s) { +static NamingConvention deriveNamingConvention(Selector S) { + IdentifierInfo *II = S.getIdentifierInfoForSlot(0); + + if (!II) + return NoConvention; + + const char *s = II->getName(); + // A method/function name may contain a prefix. We don't know it is there, // however, until we encounter the first '_'. bool InPossiblePrefix = true; @@ -145,8 +152,8 @@ static NamingConvention deriveNamingConvention(const char* s) { return C; } -static bool followsFundamentalRule(const char* s) { - return deriveNamingConvention(s) == CreateRule; +static bool followsFundamentalRule(Selector S) { + return deriveNamingConvention(S) == CreateRule; } static const ObjCMethodDecl* @@ -1218,19 +1225,17 @@ RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl* MD, if (isTrackedObjCObjectType(RetTy)) { // EXPERIMENTAL: Assume the Cocoa conventions for all objects returned // by instance methods. - RetEffect E = - followsFundamentalRule(S.getIdentifierInfoForSlot(0)->getName()) - ? ObjCAllocRetE : RetEffect::MakeNotOwned(RetEffect::ObjC); + RetEffect E = followsFundamentalRule(S) + ? ObjCAllocRetE : RetEffect::MakeNotOwned(RetEffect::ObjC); return getPersistentSummary(E, ReceiverEff, MayEscape); } // Look for methods that return an owned core foundation object. if (isTrackedCFObjectType(RetTy)) { - RetEffect E = - followsFundamentalRule(S.getIdentifierInfoForSlot(0)->getName()) - ? RetEffect::MakeOwned(RetEffect::CF, true) - : RetEffect::MakeNotOwned(RetEffect::CF); + RetEffect E = followsFundamentalRule(S) + ? RetEffect::MakeOwned(RetEffect::CF, true) + : RetEffect::MakeNotOwned(RetEffect::CF); return getPersistentSummary(E, ReceiverEff, MayEscape); } @@ -1258,8 +1263,7 @@ RetainSummaryManager::getInstanceMethodSummary(Selector S, RetainSummary *Summ = 0; // "initXXX": pass-through for receiver. - if (deriveNamingConvention(S.getIdentifierInfoForSlot(0)->getName()) - == InitRule) + if (deriveNamingConvention(S) == InitRule) Summ = getInitMethodSummary(RetTy); else Summ = getCommonMethodSummary(MD, S, RetTy); diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 74f5b90b4b..ed9f661704 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -618,6 +618,19 @@ void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) { [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning } +//===----------------------------------------------------------------------===// +// Method name that has a null IdentifierInfo* for its first selector slot. +// This test just makes sure that we handle it. +//===----------------------------------------------------------------------===// + +@interface TestNullIdentifier +@end + +@implementation TestNullIdentifier ++ (id):(int)x, ... { + return [[NSString alloc] init]; // expected-warning{{leak}} +} + //===----------------------------------------------------------------------===// // Tests of ownership attributes. //===----------------------------------------------------------------------===//