Skip to content

Commit b3303d7

Browse files
author
George Karpenkov
committedNov 30, 2018
[analyzer] [NFC] Some miscellaneous clean ups and documentation fixes.
Differential Revision: https://reviews.llvm.org/D54971 llvm-svn: 347940
1 parent 5e0b21f commit b3303d7

File tree

2 files changed

+92
-89
lines changed

2 files changed

+92
-89
lines changed
 

‎clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -260,12 +260,12 @@ class StoreManager {
260260
public:
261261
virtual ~BindingsHandler();
262262

263+
/// \return whether the iteration should continue.
263264
virtual bool HandleBinding(StoreManager& SMgr, Store store,
264265
const MemRegion *region, SVal val) = 0;
265266
};
266267

267-
class FindUniqueBinding :
268-
public BindingsHandler {
268+
class FindUniqueBinding : public BindingsHandler {
269269
SymbolRef Sym;
270270
const MemRegion* Binding = nullptr;
271271
bool First = true;

‎clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp

+90-87
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,80 @@ static bool isNumericLiteralExpression(const Expr *E) {
2828
isa<CXXBoolLiteralExpr>(E);
2929
}
3030

31+
/// Write information about the type state change to {@code os},
32+
/// return whether the note should be generated.
33+
static bool shouldGenerateNote(llvm::raw_string_ostream &os,
34+
const RefVal *PrevT, const RefVal &CurrV,
35+
SmallVector<ArgEffect, 2> &AEffects) {
36+
// Get the previous type state.
37+
RefVal PrevV = *PrevT;
38+
39+
// Specially handle -dealloc.
40+
if (std::find(AEffects.begin(), AEffects.end(), Dealloc) != AEffects.end()) {
41+
// Determine if the object's reference count was pushed to zero.
42+
assert(!PrevV.hasSameState(CurrV) && "The state should have changed.");
43+
// We may not have transitioned to 'release' if we hit an error.
44+
// This case is handled elsewhere.
45+
if (CurrV.getKind() == RefVal::Released) {
46+
assert(CurrV.getCombinedCounts() == 0);
47+
os << "Object released by directly sending the '-dealloc' message";
48+
return true;
49+
}
50+
}
51+
52+
// Determine if the typestate has changed.
53+
if (!PrevV.hasSameState(CurrV))
54+
switch (CurrV.getKind()) {
55+
case RefVal::Owned:
56+
case RefVal::NotOwned:
57+
if (PrevV.getCount() == CurrV.getCount()) {
58+
// Did an autorelease message get sent?
59+
if (PrevV.getAutoreleaseCount() == CurrV.getAutoreleaseCount())
60+
return false;
61+
62+
assert(PrevV.getAutoreleaseCount() < CurrV.getAutoreleaseCount());
63+
os << "Object autoreleased";
64+
return true;
65+
}
66+
67+
if (PrevV.getCount() > CurrV.getCount())
68+
os << "Reference count decremented.";
69+
else
70+
os << "Reference count incremented.";
71+
72+
if (unsigned Count = CurrV.getCount())
73+
os << " The object now has a +" << Count << " retain count.";
74+
75+
return true;
76+
77+
case RefVal::Released:
78+
if (CurrV.getIvarAccessHistory() ==
79+
RefVal::IvarAccessHistory::ReleasedAfterDirectAccess &&
80+
CurrV.getIvarAccessHistory() != PrevV.getIvarAccessHistory()) {
81+
os << "Strong instance variable relinquished. ";
82+
}
83+
os << "Object released.";
84+
return true;
85+
86+
case RefVal::ReturnedOwned:
87+
// Autoreleases can be applied after marking a node ReturnedOwned.
88+
if (CurrV.getAutoreleaseCount())
89+
return false;
90+
91+
os << "Object returned to caller as an owning reference (single "
92+
"retain count transferred to caller)";
93+
return true;
94+
95+
case RefVal::ReturnedNotOwned:
96+
os << "Object returned to caller with a +0 retain count";
97+
return true;
98+
99+
default:
100+
return false;
101+
}
102+
return true;
103+
}
104+
31105
std::shared_ptr<PathDiagnosticPiece>
32106
CFRefReportVisitor::VisitNode(const ExplodedNode *N,
33107
BugReporterContext &BRC, BugReport &BR) {
@@ -64,11 +138,9 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N,
64138

65139
if (isa<ObjCArrayLiteral>(S)) {
66140
os << "NSArray literal is an object with a +0 retain count";
67-
}
68-
else if (isa<ObjCDictionaryLiteral>(S)) {
141+
} else if (isa<ObjCDictionaryLiteral>(S)) {
69142
os << "NSDictionary literal is an object with a +0 retain count";
70-
}
71-
else if (const ObjCBoxedExpr *BL = dyn_cast<ObjCBoxedExpr>(S)) {
143+
} else if (const ObjCBoxedExpr *BL = dyn_cast<ObjCBoxedExpr>(S)) {
72144
if (isNumericLiteralExpression(BL->getSubExpr()))
73145
os << "NSNumber literal is an object with a +0 retain count";
74146
else {
@@ -78,27 +150,26 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N,
78150

79151
// We should always be able to find the boxing class interface,
80152
// but consider this future-proofing.
81-
if (BoxClass)
153+
if (BoxClass) {
82154
os << *BoxClass << " b";
83-
else
155+
} else {
84156
os << "B";
157+
}
85158

86159
os << "oxed expression produces an object with a +0 retain count";
87160
}
88-
}
89-
else if (isa<ObjCIvarRefExpr>(S)) {
161+
} else if (isa<ObjCIvarRefExpr>(S)) {
90162
os << "Object loaded from instance variable";
91-
}
92-
else {
163+
} else {
93164
if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
94165
// Get the name of the callee (if it is available).
95166
SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee(), LCtx);
96-
if (const FunctionDecl *FD = X.getAsFunctionDecl())
167+
if (const FunctionDecl *FD = X.getAsFunctionDecl()) {
97168
os << "Call to function '" << *FD << '\'';
98-
else
169+
} else {
99170
os << "function call";
100-
}
101-
else {
171+
}
172+
} else {
102173
assert(isa<ObjCMessageExpr>(S));
103174
CallEventManager &Mgr = CurrSt->getStateManager().getCallEventManager();
104175
CallEventRef<ObjCMethodCall> Call
@@ -166,8 +237,7 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N,
166237
// was ever passed as an argument.
167238
unsigned i = 0;
168239

169-
for (CallExpr::const_arg_iterator AI=CE->arg_begin(), AE=CE->arg_end();
170-
AI!=AE; ++AI, ++i) {
240+
for (auto AI=CE->arg_begin(), AE=CE->arg_end(); AI!=AE; ++AI, ++i) {
171241

172242
// Retrieve the value of the argument. Is it the symbol
173243
// we are interested in?
@@ -188,75 +258,8 @@ CFRefReportVisitor::VisitNode(const ExplodedNode *N,
188258
}
189259
}
190260

191-
do {
192-
// Get the previous type state.
193-
RefVal PrevV = *PrevT;
194-
195-
// Specially handle -dealloc.
196-
if (std::find(AEffects.begin(), AEffects.end(), Dealloc) !=
197-
AEffects.end()) {
198-
// Determine if the object's reference count was pushed to zero.
199-
assert(!PrevV.hasSameState(CurrV) && "The state should have changed.");
200-
// We may not have transitioned to 'release' if we hit an error.
201-
// This case is handled elsewhere.
202-
if (CurrV.getKind() == RefVal::Released) {
203-
assert(CurrV.getCombinedCounts() == 0);
204-
os << "Object released by directly sending the '-dealloc' message";
205-
break;
206-
}
207-
}
208-
209-
// Determine if the typestate has changed.
210-
if (!PrevV.hasSameState(CurrV))
211-
switch (CurrV.getKind()) {
212-
case RefVal::Owned:
213-
case RefVal::NotOwned:
214-
if (PrevV.getCount() == CurrV.getCount()) {
215-
// Did an autorelease message get sent?
216-
if (PrevV.getAutoreleaseCount() == CurrV.getAutoreleaseCount())
217-
return nullptr;
218-
219-
assert(PrevV.getAutoreleaseCount() < CurrV.getAutoreleaseCount());
220-
os << "Object autoreleased";
221-
break;
222-
}
223-
224-
if (PrevV.getCount() > CurrV.getCount())
225-
os << "Reference count decremented.";
226-
else
227-
os << "Reference count incremented.";
228-
229-
if (unsigned Count = CurrV.getCount())
230-
os << " The object now has a +" << Count << " retain count.";
231-
232-
break;
233-
234-
case RefVal::Released:
235-
if (CurrV.getIvarAccessHistory() ==
236-
RefVal::IvarAccessHistory::ReleasedAfterDirectAccess &&
237-
CurrV.getIvarAccessHistory() != PrevV.getIvarAccessHistory()) {
238-
os << "Strong instance variable relinquished. ";
239-
}
240-
os << "Object released.";
241-
break;
242-
243-
case RefVal::ReturnedOwned:
244-
// Autoreleases can be applied after marking a node ReturnedOwned.
245-
if (CurrV.getAutoreleaseCount())
246-
return nullptr;
247-
248-
os << "Object returned to caller as an owning reference (single "
249-
"retain count transferred to caller)";
250-
break;
251-
252-
case RefVal::ReturnedNotOwned:
253-
os << "Object returned to caller with a +0 retain count";
254-
break;
255-
256-
default:
257-
return nullptr;
258-
}
259-
} while (0);
261+
if (!shouldGenerateNote(os, PrevT, CurrV, AEffects))
262+
return nullptr;
260263

261264
if (os.str().empty())
262265
return nullptr; // We have nothing to say!
@@ -428,9 +431,9 @@ CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
428431
Optional<std::string> RegionDescription = describeRegion(FirstBinding);
429432
if (RegionDescription) {
430433
os << "object allocated and stored into '" << *RegionDescription << '\'';
431-
}
432-
else
434+
} else {
433435
os << "allocated object";
436+
}
434437

435438
// Get the retain count.
436439
const RefVal* RV = getRefBinding(EndN->getState(), Sym);

0 commit comments

Comments
 (0)
Please sign in to comment.