Skip to content

Commit

Permalink
[analyzer] Re-instate support for MakeCollectable is RetainCountChecker
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D50872

llvm-svn: 340097
  • Loading branch information
George Karpenkov committed Aug 17, 2018
1 parent 03011b2 commit bc0cddf
Show file tree
Hide file tree
Showing 7 changed files with 679 additions and 522 deletions.
3 changes: 3 additions & 0 deletions clang/include/clang/Analysis/ObjCRetainCount.h
Expand Up @@ -65,6 +65,9 @@ enum ArgEffect {
/// if CFRetain has been called on the argument.
IncRef,

/// Used to mark an argument as collectible in GC mode, currently a noop.
MakeCollectable,

/// The argument is a pointer to a retain-counted object; on exit, the new
/// value of the pointer is a +0 value or NULL.
UnretainedOutParameter,
Expand Down
Expand Up @@ -581,6 +581,8 @@ RetainCountChecker::updateSymbol(ProgramStateRef state, SymbolRef sym,
case DecRefMsgAndStopTrackingHard:
E = IgnoreRetainMsg ? StopTracking : DecRefAndStopTrackingHard;
break;
case MakeCollectable:
E = DoNothing;
}

// Handle all use-after-releases.
Expand All @@ -593,8 +595,9 @@ RetainCountChecker::updateSymbol(ProgramStateRef state, SymbolRef sym,
switch (E) {
case DecRefMsg:
case IncRefMsg:
case MakeCollectable:
case DecRefMsgAndStopTrackingHard:
llvm_unreachable("DecRefMsg/IncRefMsg already converted");
llvm_unreachable("DecRefMsg/IncRefMsg/MakeCollectable already converted");

case UnretainedOutParameter:
case RetainedOutParameter:
Expand Down
Expand Up @@ -78,6 +78,10 @@ static bool isAutorelease(const FunctionDecl *FD, StringRef FName) {
FName.endswith_lower("autorelease");
}

static bool isMakeCollectable(StringRef FName) {
return FName.contains_lower("MakeCollectable");
}

const RetainSummary *
RetainSummaryManager::generateSummary(const FunctionDecl *FD,
bool &AllowAnnotations) {
Expand Down Expand Up @@ -111,6 +115,11 @@ RetainSummaryManager::generateSummary(const FunctionDecl *FD,
// Part of: <rdar://problem/7299394> and <rdar://problem/11282706>.
// This will be addressed better with IPA.
return getPersistentStopSummary();
} else if(FName == "NSMakeCollectable") {
// Handle: id NSMakeCollectable(CFTypeRef)
AllowAnnotations = false;
return RetTy->isObjCIdType() ? getUnarySummary(FT, cfmakecollectable)
: getPersistentStopSummary();
} else if (FName == "CFPlugInInstanceCreate") {
return getPersistentSummary(RetEffect::MakeNoRet());
} else if (FName == "IORegistryEntrySearchCFProperty" ||
Expand Down Expand Up @@ -207,6 +216,9 @@ RetainSummaryManager::generateSummary(const FunctionDecl *FD,
AllowAnnotations = false;

return getUnarySummary(FT, cfautorelease);
} else if (isMakeCollectable(FName)) {
AllowAnnotations = false;
return getUnarySummary(FT, cfmakecollectable);
} else {
return getCFCreateGetRuleSummary(FD);
}
Expand Down Expand Up @@ -301,14 +313,14 @@ RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) {
// Summary creation for functions (largely uses of Core Foundation).
//===----------------------------------------------------------------------===//


static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) {
switch (E) {
case DoNothing:
case Autorelease:
case DecRefBridgedTransferred:
case IncRef:
case IncRefMsg:
case MakeCollectable:
case UnretainedOutParameter:
case RetainedOutParameter:
case MayEscape:
Expand Down Expand Up @@ -458,14 +470,17 @@ bool RetainSummaryManager::canEval(const CallExpr *CE,
FName = FName.substr(FName.find_first_not_of('_'));

QualType ResultTy = CE->getCallReturnType(Ctx);
if (ResultTy->isPointerType()) {
if (ResultTy->isObjCIdType()) {
return II->isStr("NSMakeCollectable");
} else if (ResultTy->isPointerType()) {
// Handle: (CF|CG|CV)Retain
// CFAutorelease
// It's okay to be a little sloppy here.
if (cocoa::isRefType(ResultTy, "CF", FName) ||
cocoa::isRefType(ResultTy, "CG", FName) ||
cocoa::isRefType(ResultTy, "CV", FName))
return isRetain(FD, FName) || isAutorelease(FD, FName);
return isRetain(FD, FName) || isAutorelease(FD, FName) ||
isMakeCollectable(FName);

if (FD->getDefinition()) {
bool out = isTrustedReferenceCountImplementation(FD->getDefinition());
Expand Down Expand Up @@ -495,6 +510,7 @@ RetainSummaryManager::getUnarySummary(const FunctionType* FT,
case cfretain: Effect = IncRef; break;
case cfrelease: Effect = DecRef; break;
case cfautorelease: Effect = Autorelease; break;
case cfmakecollectable: Effect = MakeCollectable; break;
}

ScratchArgs = AF.add(ScratchArgs, 0, Effect);
Expand Down
Expand Up @@ -315,7 +315,7 @@ class RetainSummaryManager {
/// data in ScratchArgs.
ArgEffects getArgEffects();

enum UnaryFuncKind { cfretain, cfrelease, cfautorelease };
enum UnaryFuncKind { cfretain, cfrelease, cfautorelease, cfmakecollectable };

const RetainSummary *getUnarySummary(const FunctionType* FT,
UnaryFuncKind func);
Expand Down

0 comments on commit bc0cddf

Please sign in to comment.