Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 13 additions & 25 deletions clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class NilArgChecker : public Checker<check::PreObjCMessage,
check::PostStmt<ObjCDictionaryLiteral>,
check::PostStmt<ObjCArrayLiteral>,
EventDispatcher<ImplicitNullDerefEvent>> {
mutable std::unique_ptr<APIMisuse> BT;
const APIMisuse BT{this, "nil argument"};

mutable llvm::SmallDenseMap<Selector, unsigned, 16> StringSelectors;
mutable Selector ArrayWithObjectSel;
Expand Down Expand Up @@ -218,10 +218,7 @@ void NilArgChecker::generateBugReport(ExplodedNode *N,
SourceRange Range,
const Expr *E,
CheckerContext &C) const {
if (!BT)
BT.reset(new APIMisuse(this, "nil argument"));

auto R = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);
R->addRange(Range);
bugreporter::trackExpressionValue(N, E, *R);
C.emitReport(std::move(R));
Expand Down Expand Up @@ -350,7 +347,7 @@ void NilArgChecker::checkPostStmt(const ObjCDictionaryLiteral *DL,

namespace {
class CFNumberChecker : public Checker< check::PreStmt<CallExpr> > {
mutable std::unique_ptr<APIMisuse> BT;
const APIMisuse BT{this, "Bad use of CFNumber APIs"};
mutable IdentifierInfo *ICreate = nullptr, *IGetValue = nullptr;
public:
CFNumberChecker() = default;
Expand Down Expand Up @@ -524,10 +521,7 @@ void CFNumberChecker::checkPreStmt(const CallExpr *CE,
<< " bits of the integer value will be "
<< (isCreate ? "lost." : "garbage.");

if (!BT)
BT.reset(new APIMisuse(this, "Bad use of CFNumber APIs"));

auto report = std::make_unique<PathSensitiveBugReport>(*BT, os.str(), N);
auto report = std::make_unique<PathSensitiveBugReport>(BT, os.str(), N);
report->addRange(CE->getArg(2)->getSourceRange());
C.emitReport(std::move(report));
}
Expand All @@ -539,7 +533,7 @@ void CFNumberChecker::checkPreStmt(const CallExpr *CE,

namespace {
class CFRetainReleaseChecker : public Checker<check::PreCall> {
mutable APIMisuse BT{this, "null passed to CF memory management function"};
const APIMisuse BT{this, "null passed to CF memory management function"};
const CallDescriptionSet ModelledCalls = {
{CDM::CLibrary, {"CFRetain"}, 1},
{CDM::CLibrary, {"CFRelease"}, 1},
Expand Down Expand Up @@ -600,7 +594,8 @@ class ClassReleaseChecker : public Checker<check::PreObjCMessage> {
mutable Selector retainS;
mutable Selector autoreleaseS;
mutable Selector drainS;
mutable std::unique_ptr<BugType> BT;
const APIMisuse BT{
this, "message incorrectly sent to class instead of class instance"};

public:
void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
Expand All @@ -609,10 +604,7 @@ class ClassReleaseChecker : public Checker<check::PreObjCMessage> {

void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
CheckerContext &C) const {
if (!BT) {
BT.reset(new APIMisuse(
this, "message incorrectly sent to class instead of class instance"));

if (releaseS.isNull()) {
ASTContext &Ctx = C.getASTContext();
releaseS = GetNullarySelector("release", Ctx);
retainS = GetNullarySelector("retain", Ctx);
Expand All @@ -639,7 +631,7 @@ void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
"of class '" << Class->getName()
<< "' and not the class directly";

auto report = std::make_unique<PathSensitiveBugReport>(*BT, os.str(), N);
auto report = std::make_unique<PathSensitiveBugReport>(BT, os.str(), N);
report->addRange(msg.getSourceRange());
C.emitReport(std::move(report));
}
Expand All @@ -658,7 +650,8 @@ class VariadicMethodTypeChecker : public Checker<check::PreObjCMessage> {
mutable Selector orderedSetWithObjectsS;
mutable Selector initWithObjectsS;
mutable Selector initWithObjectsAndKeysS;
mutable std::unique_ptr<BugType> BT;
const APIMisuse BT{this, "Arguments passed to variadic method aren't all "
"Objective-C pointer types"};

bool isVariadicMessage(const ObjCMethodCall &msg) const;

Expand Down Expand Up @@ -717,11 +710,7 @@ VariadicMethodTypeChecker::isVariadicMessage(const ObjCMethodCall &msg) const {

void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
CheckerContext &C) const {
if (!BT) {
BT.reset(new APIMisuse(this,
"Arguments passed to variadic method aren't all "
"Objective-C pointer types"));

if (arrayWithObjectsS.isNull()) {
ASTContext &Ctx = C.getASTContext();
arrayWithObjectsS = GetUnarySelector("arrayWithObjects", Ctx);
dictionaryWithObjectsAndKeysS =
Expand Down Expand Up @@ -792,8 +781,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
ArgTy.print(os, C.getLangOpts());
os << "'";

auto R =
std::make_unique<PathSensitiveBugReport>(*BT, os.str(), *errorNode);
auto R = std::make_unique<PathSensitiveBugReport>(BT, os.str(), *errorNode);
R->addRange(msg.getArgSourceRange(I));
C.emitReport(std::move(R));
}
Expand Down