From e7d03121afaba80ccfdde83d3584149e301ec5af Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 8 Feb 2010 16:45:01 +0000 Subject: [PATCH] Revert 95546 since it changed the algorithmic characteristics of the convention lookup. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95547 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checker/DomainSpecific/CocoaConventions.h | 4 +- lib/Checker/CFRefCount.cpp | 215 ++++++++++++------ lib/Checker/CocoaConventions.cpp | 10 +- 3 files changed, 153 insertions(+), 76 deletions(-) diff --git a/include/clang/Checker/DomainSpecific/CocoaConventions.h b/include/clang/Checker/DomainSpecific/CocoaConventions.h index ee3d648b86..b50b992224 100644 --- a/include/clang/Checker/DomainSpecific/CocoaConventions.h +++ b/include/clang/Checker/DomainSpecific/CocoaConventions.h @@ -28,8 +28,8 @@ namespace cocoa { return deriveNamingConvention(S) == CreateRule; } - bool isRefType(QualType RetTy, llvm::StringRef Prefix, - llvm::StringRef Name = llvm::StringRef()); + bool isRefType(QualType RetTy, const char* prefix, + const char* name = 0); bool isCFObjectRef(QualType T); diff --git a/lib/Checker/CFRefCount.cpp b/lib/Checker/CFRefCount.cpp index 554196f00f..85d9dbdce1 100644 --- a/lib/Checker/CFRefCount.cpp +++ b/lib/Checker/CFRefCount.cpp @@ -705,7 +705,7 @@ public: RetainSummary* getCFSummaryCreateRule(FunctionDecl* FD); RetainSummary* getCFSummaryGetRule(FunctionDecl* FD); - RetainSummary* getCFCreateGetRuleSummary(FunctionDecl* FD, StringRef FName); + RetainSummary* getCFCreateGetRuleSummary(FunctionDecl* FD, const char* FName); RetainSummary* getPersistentSummary(ArgEffects AE, RetEffect RetEff, ArgEffect ReceiverEff = DoNothing, @@ -923,12 +923,14 @@ RetainSummaryManager::getPersistentSummary(ArgEffects AE, RetEffect RetEff, // Summary creation for functions (largely uses of Core Foundation). //===----------------------------------------------------------------------===// -static bool isRetain(FunctionDecl* FD, StringRef FName) { - return FName.endswith("Retain"); +static bool isRetain(FunctionDecl* FD, const char* FName) { + const char* loc = strstr(FName, "Retain"); + return loc && loc[sizeof("Retain")-1] == '\0'; } -static bool isRelease(FunctionDecl* FD, StringRef FName) { - return FName.endswith("Release"); +static bool isRelease(FunctionDecl* FD, const char* FName) { + const char* loc = strstr(FName, "Release"); + return loc && loc[sizeof("Release")-1] == '\0'; } RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) { @@ -953,12 +955,12 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) { const IdentifierInfo *II = FD->getIdentifier(); if (!II) break; - - StringRef FName = II->getName(); + + const char* FName = II->getNameStart(); // Strip away preceding '_'. Doing this here will effect all the checks // down below. - FName = FName.substr(FName.find_first_not_of('_')); + while (*FName == '_') ++FName; // Inspect the result type. QualType RetTy = FT->getResultType(); @@ -966,63 +968,133 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) { // FIXME: This should all be refactored into a chain of "summary lookup" // filters. assert(ScratchArgs.isEmpty()); + + switch (strlen(FName)) { + default: break; + case 14: + if (!memcmp(FName, "pthread_create", 14)) { + // Part of: . This will be addressed + // better with IPA. + S = getPersistentStopSummary(); + } + break; - if (FName == "pthread_create") { - // Part of: . This will be addressed - // better with IPA. - S = getPersistentStopSummary(); - } else if (FName == "NSMakeCollectable") { - // Handle: id NSMakeCollectable(CFTypeRef) - S = (RetTy->isObjCIdType()) - ? getUnarySummary(FT, cfmakecollectable) - : getPersistentStopSummary(); - } else if (FName == "IOBSDNameMatching" || - FName == "IOServiceMatching" || - FName == "IOServiceNameMatching" || - FName == "IORegistryEntryIDMatching" || - FName == "IOOpenFirmwarePathMatching") { - // Part of . (IOKit) - // This should be addressed using a API table. - S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true), - DoNothing, DoNothing); - } else if (FName == "IOServiceGetMatchingService" || - FName == "IOServiceGetMatchingServices") { - // FIXES: - // This should be addressed using a API table. This strcmp is also - // a little gross, but there is no need to super optimize here. - ScratchArgs = AF.Add(ScratchArgs, 1, DecRef); - S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); - } else if (FName == "IOServiceAddNotification" || - FName == "IOServiceAddMatchingNotification") { - // Part of . (IOKit) - // This should be addressed using a API table. - ScratchArgs = AF.Add(ScratchArgs, 2, DecRef); - S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); - } else if (FName == "CVPixelBufferCreateWithBytes") { - // FIXES: - // Eventually this can be improved by recognizing that the pixel - // buffer passed to CVPixelBufferCreateWithBytes is released via - // a callback and doing full IPA to make sure this is done correctly. - // FIXME: This function has an out parameter that returns an - // allocated object. - ScratchArgs = AF.Add(ScratchArgs, 7, StopTracking); - S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); - } else if (FName == "CGBitmapContextCreateWithData") { - // FIXES: - // Eventually this can be improved by recognizing that 'releaseInfo' - // passed to CGBitmapContextCreateWithData is released via - // a callback and doing full IPA to make sure this is done correctly. - ScratchArgs = AF.Add(ScratchArgs, 8, StopTracking); - S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true), - DoNothing, DoNothing); - } else if (FName == "CVPixelBufferCreateWithPlanarBytes") { - // FIXES: - // Eventually this can be improved by recognizing that the pixel - // buffer passed to CVPixelBufferCreateWithPlanarBytes is released - // via a callback and doing full IPA to make sure this is done - // correctly. - ScratchArgs = AF.Add(ScratchArgs, 12, StopTracking); - S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); + case 17: + // Handle: id NSMakeCollectable(CFTypeRef) + if (!memcmp(FName, "NSMakeCollectable", 17)) { + S = (RetTy->isObjCIdType()) + ? getUnarySummary(FT, cfmakecollectable) + : getPersistentStopSummary(); + } + else if (!memcmp(FName, "IOBSDNameMatching", 17) || + !memcmp(FName, "IOServiceMatching", 17)) { + // Part of . (IOKit) + // This should be addressed using a API table. + S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true), + DoNothing, DoNothing); + } + break; + + case 21: + if (!memcmp(FName, "IOServiceNameMatching", 21)) { + // Part of . (IOKit) + // This should be addressed using a API table. + S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true), + DoNothing, DoNothing); + } + break; + + case 24: + if (!memcmp(FName, "IOServiceAddNotification", 24)) { + // Part of . (IOKit) + // This should be addressed using a API table. + ScratchArgs = AF.Add(ScratchArgs, 2, DecRef); + S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing,DoNothing); + } + break; + + case 25: + if (!memcmp(FName, "IORegistryEntryIDMatching", 25)) { + // Part of . (IOKit) + // This should be addressed using a API table. + S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true), + DoNothing, DoNothing); + } + break; + + case 26: + if (!memcmp(FName, "IOOpenFirmwarePathMatching", 26)) { + // Part of . (IOKit) + // This should be addressed using a API table. + S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true), + DoNothing, DoNothing); + } + break; + + case 27: + if (!memcmp(FName, "IOServiceGetMatchingService", 27)) { + // Part of . + // This should be addressed using a API table. + ScratchArgs = AF.Add(ScratchArgs, 1, DecRef); + S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); + } + break; + + case 28: + if (!memcmp(FName, "IOServiceGetMatchingServices", 28)) { + // FIXES: + // This should be addressed using a API table. This strcmp is also + // a little gross, but there is no need to super optimize here. + ScratchArgs = AF.Add(ScratchArgs, 1, DecRef); + S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, + DoNothing); + } + else if (!memcmp(FName, "CVPixelBufferCreateWithBytes", 28)) { + // FIXES: + // Eventually this can be improved by recognizing that the pixel + // buffer passed to CVPixelBufferCreateWithBytes is released via + // a callback and doing full IPA to make sure this is done correctly. + // FIXME: This function has an out parameter that returns an + // allocated object. + ScratchArgs = AF.Add(ScratchArgs, 7, StopTracking); + S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, + DoNothing); + } + break; + + case 29: + if (!memcmp(FName, "CGBitmapContextCreateWithData", 29)) { + // FIXES: + // Eventually this can be improved by recognizing that 'releaseInfo' + // passed to CGBitmapContextCreateWithData is released via + // a callback and doing full IPA to make sure this is done correctly. + ScratchArgs = AF.Add(ScratchArgs, 8, StopTracking); + S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true), + DoNothing,DoNothing); + } + break; + + case 32: + if (!memcmp(FName, "IOServiceAddMatchingNotification", 32)) { + // Part of . + // This should be addressed using a API table. + ScratchArgs = AF.Add(ScratchArgs, 2, DecRef); + S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing); + } + break; + + case 34: + if (!memcmp(FName, "CVPixelBufferCreateWithPlanarBytes", 34)) { + // FIXES: + // Eventually this can be improved by recognizing that the pixel + // buffer passed to CVPixelBufferCreateWithPlanarBytes is released + // via a callback and doing full IPA to make sure this is done + // correctly. + ScratchArgs = AF.Add(ScratchArgs, 12, StopTracking); + S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, + DoNothing); + } + break; } // Did we get a summary? @@ -1046,7 +1118,7 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) { if (cocoa::isRefType(RetTy, "CF", FName)) { if (isRetain(FD, FName)) S = getUnarySummary(FT, cfretain); - else if (FName.find("MakeCollectable") != StringRef::npos) + else if (strstr(FName, "MakeCollectable")) S = getUnarySummary(FT, cfmakecollectable); else S = getCFCreateGetRuleSummary(FD, FName); @@ -1078,6 +1150,12 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) { // Check for release functions, the only kind of functions that we care // about that don't return a pointer type. if (FName[0] == 'C' && (FName[1] == 'F' || FName[1] == 'G')) { + // Test for 'CGCF'. + if (FName[1] == 'G' && FName[2] == 'C' && FName[3] == 'F') + FName += 4; + else + FName += 2; + if (isRelease(FD, FName)) S = getUnarySummary(FT, cfrelease); else { @@ -1123,13 +1201,12 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) { RetainSummary* RetainSummaryManager::getCFCreateGetRuleSummary(FunctionDecl* FD, - StringRef FName) { + const char* FName) { - if (FName.find("Create") != StringRef::npos || - FName.find("Copy") != StringRef::npos) + if (strstr(FName, "Create") || strstr(FName, "Copy")) return getCFSummaryCreateRule(FD); - if (FName.find("Get") != StringRef::npos) + if (strstr(FName, "Get")) return getCFSummaryGetRule(FD); return getDefaultSummary(); diff --git a/lib/Checker/CocoaConventions.cpp b/lib/Checker/CocoaConventions.cpp index 9198b3be80..ff3a0c97b4 100644 --- a/lib/Checker/CocoaConventions.cpp +++ b/lib/Checker/CocoaConventions.cpp @@ -131,19 +131,19 @@ cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S) { return C; } -bool cocoa::isRefType(QualType RetTy, llvm::StringRef Prefix, - llvm::StringRef Name) { +bool cocoa::isRefType(QualType RetTy, const char* prefix, + const char* name) { // Recursively walk the typedef stack, allowing typedefs of reference types. while (TypedefType* TD = dyn_cast(RetTy.getTypePtr())) { llvm::StringRef TDName = TD->getDecl()->getIdentifier()->getName(); - if (TDName.startswith(Prefix) && TDName.endswith("Ref")) + if (TDName.startswith(prefix) && TDName.endswith("Ref")) return true; RetTy = TD->getDecl()->getUnderlyingType(); } - if (Name.empty()) + if (!name) return false; // Is the type void*? @@ -152,7 +152,7 @@ bool cocoa::isRefType(QualType RetTy, llvm::StringRef Prefix, return false; // Does the name start with the prefix? - return Name.startswith(Prefix); + return llvm::StringRef(name).startswith(prefix); } bool cocoa::isCFObjectRef(QualType T) { -- 2.40.0