Skip to content

Commit be3f4bd

Browse files
author
George Karpenkov
committed
Revert "Reverting r347949-r347951 because they broke the test bots."
This reverts commit 5bad6129c012fbf186eb055be49344e790448ecc. Hopefully fixing the issue which was breaking the bots. llvm-svn: 348030
1 parent e64fe2a commit be3f4bd

File tree

3 files changed

+53
-11
lines changed

3 files changed

+53
-11
lines changed

clang/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,8 @@ class RetainSummaryManager {
530530
/// Decrement the reference count on OS object.
531531
const RetainSummary *getOSSummaryReleaseRule(const FunctionDecl *FD);
532532

533+
/// Free the OS object.
534+
const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD);
533535

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

clang/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,8 @@ RetainSummaryManager::generateSummary(const FunctionDecl *FD,
124124
}
125125

126126
const IdentifierInfo *II = FD->getIdentifier();
127-
if (!II)
128-
return getDefaultSummary();
129127

130-
StringRef FName = II->getName();
128+
StringRef FName = II ? II->getName() : "";
131129

132130
// Strip away preceding '_'. Doing this here will effect all the checks
133131
// down below.
@@ -304,6 +302,12 @@ RetainSummaryManager::generateSummary(const FunctionDecl *FD,
304302

305303
if (FName == "retain")
306304
return getOSSummaryRetainRule(FD);
305+
306+
if (FName == "free")
307+
return getOSSummaryFreeRule(FD);
308+
309+
if (MD->getOverloadedOperator() == OO_New)
310+
return getOSSummaryCreateRule(MD);
307311
}
308312
}
309313

@@ -480,20 +484,14 @@ RetainSummaryManager::getSummary(const CallEvent &Call,
480484
const RetainSummary *Summ;
481485
switch (Call.getKind()) {
482486
case CE_Function:
483-
Summ = getFunctionSummary(cast<SimpleFunctionCall>(Call).getDecl());
484-
break;
485487
case CE_CXXMember:
486-
Summ = getFunctionSummary(cast<CXXMemberCall>(Call).getDecl());
487-
break;
488488
case CE_CXXMemberOperator:
489-
Summ = getFunctionSummary(cast<CXXMemberOperatorCall>(Call).getDecl());
490-
break;
491489
case CE_CXXConstructor:
492-
Summ = getFunctionSummary(cast<CXXConstructorCall>(Call).getDecl());
490+
case CE_CXXAllocator:
491+
Summ = getFunctionSummary(cast_or_null<FunctionDecl>(Call.getDecl()));
493492
break;
494493
case CE_Block:
495494
case CE_CXXDestructor:
496-
case CE_CXXAllocator:
497495
// FIXME: These calls are currently unsupported.
498496
return getPersistentStopSummary();
499497
case CE_ObjCMessage: {
@@ -618,6 +616,14 @@ RetainSummaryManager::getOSSummaryReleaseRule(const FunctionDecl *FD) {
618616
/*ThisEff=*/DecRef);
619617
}
620618

619+
const RetainSummary *
620+
RetainSummaryManager::getOSSummaryFreeRule(const FunctionDecl *FD) {
621+
return getPersistentSummary(RetEffect::MakeNoRet(),
622+
/*ReceiverEff=*/DoNothing,
623+
/*DefaultEff=*/DoNothing,
624+
/*ThisEff=*/Dealloc);
625+
}
626+
621627
const RetainSummary *
622628
RetainSummaryManager::getOSSummaryCreateRule(const FunctionDecl *FD) {
623629
return getPersistentSummary(RetEffect::MakeOwned(RetEffect::OS));

clang/test/Analysis/osobject-retain-release.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ struct OSMetaClass;
1111
#define OSDynamicCast(type, inst) \
1212
((type *) OSMetaClassBase::safeMetaCast((inst), OSTypeID(type)))
1313

14+
using size_t = decltype(sizeof(int));
15+
1416
struct OSObject {
1517
virtual void retain();
1618
virtual void release() {};
19+
virtual void free();
1720
virtual ~OSObject(){}
1821

1922
unsigned int foo() { return 42; }
@@ -23,6 +26,9 @@ struct OSObject {
2326
static OSObject *getObject();
2427
static OSObject *GetObject();
2528

29+
30+
static void * operator new(size_t size);
31+
2632
static const OSMetaClass * const metaClass;
2733
};
2834

@@ -62,6 +68,34 @@ struct OSMetaClassBase {
6268
static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
6369
};
6470

71+
void check_free_no_error() {
72+
OSArray *arr = OSArray::withCapacity(10);
73+
arr->retain();
74+
arr->retain();
75+
arr->retain();
76+
arr->free();
77+
}
78+
79+
void check_free_use_after_free() {
80+
OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
81+
arr->retain(); // expected-note{{Reference count incremented. The object now has a +2 retain count}}
82+
arr->free(); // expected-note{{Object released}}
83+
arr->retain(); // expected-warning{{Reference-counted object is used after it is released}}
84+
// expected-note@-1{{Reference-counted object is used after it is released}}
85+
}
86+
87+
unsigned int check_leak_explicit_new() {
88+
OSArray *arr = new OSArray; // expected-note{{Operator new returns an OSObject of type OSArray with a +1 retain count}}
89+
return arr->getCount(); // expected-note{{Object leaked: allocated object of type OSArray is not referenced later in this execution path and has a retain count of +1}}
90+
// expected-warning@-1{{Potential leak of an object of type OSArray}}
91+
}
92+
93+
unsigned int check_leak_factory() {
94+
OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
95+
return arr->getCount(); // expected-note{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}}
96+
// expected-warning@-1{{Potential leak of an object stored into 'arr'}}
97+
}
98+
6599
void check_get_object() {
66100
OSObject::getObject();
67101
}

0 commit comments

Comments
 (0)