21 #include "llvm/ADT/DenseSet.h"
23 using namespace clang;
28 class UncountedCallArgsChecker
29 :
public Checker<check::ASTDecl<TranslationUnitDecl>> {
31 "Uncounted call argument for a raw pointer/reference parameter",
32 "WebKit coding guidelines"};
33 mutable BugReporter *BR;
38 BugReporter &BRArg)
const {
45 const UncountedCallArgsChecker *Checker;
46 explicit LocalVisitor(
const UncountedCallArgsChecker *Checker)
51 bool shouldVisitTemplateInstantiations()
const {
return true; }
52 bool shouldVisitImplicitCode()
const {
return false; }
54 bool VisitCallExpr(
const CallExpr *CE) {
55 Checker->visitCallExpr(CE);
60 LocalVisitor visitor(
this);
64 void visitCallExpr(
const CallExpr *CE)
const {
65 if (shouldSkipCall(CE))
71 unsigned ArgIdx = isa<CXXOperatorCallExpr>(CE) && isa_and_nonnull<CXXMethodDecl>(F);
73 for (
auto P = F->param_begin();
78 P < F->param_end() && ArgIdx < CE->getNumArgs(); ++
P, ++ArgIdx) {
83 const auto *ArgType = (*P)->getType().getTypePtrOrNull();
89 if (!IsUncounted || !(*IsUncounted))
92 const auto *Arg = CE->
getArg(ArgIdx);
94 std::pair<const clang::Expr *, bool> ArgOrigin =
102 if (isa<CXXNullPtrLiteralExpr>(ArgOrigin.first)) {
106 if (isa<IntegerLiteral>(ArgOrigin.first)) {
120 bool shouldSkipCall(
const CallExpr *CE)
const {
126 if (
auto *MemberOp = dyn_cast<CXXOperatorCallExpr>(CE)) {
128 if (MemberOp->isAssignmentOp())
136 auto overloadedOperatorType =
Callee->getOverloadedOperator();
137 if (overloadedOperatorType == OO_EqualEqual ||
138 overloadedOperatorType == OO_ExclaimEqual ||
139 overloadedOperatorType == OO_LessEqual ||
140 overloadedOperatorType == OO_GreaterEqual ||
141 overloadedOperatorType == OO_Spaceship ||
142 overloadedOperatorType == OO_AmpAmp ||
143 overloadedOperatorType == OO_PipePipe)
150 if (
name ==
"adoptRef" ||
name ==
"getPtr" ||
name ==
"WeakPtr" ||
151 name ==
"makeWeakPtr" ||
name ==
"downcast" ||
name ==
"bitwise_cast" ||
155 ||
name ==
"equalIgnoringASCIICase" ||
156 name ==
"equalIgnoringASCIICaseCommon" ||
157 name ==
"equalIgnoringNullity")
167 llvm::raw_svector_ostream Os(Buf);
170 Os <<
"Call argument";
171 if (!paramName.empty()) {
172 Os <<
" for parameter ";
175 Os <<
" is uncounted and unsafe.";
181 PathDiagnosticLocation BSLoc(SrcLocToReport, BR->getSourceManager());
182 auto Report = std::make_unique<BasicBugReport>(Bug, Os.str(), BSLoc);
184 BR->emitReport(std::move(Report));
189 void ento::registerUncountedCallArgsChecker(CheckerManager &Mgr) {
190 Mgr.registerChecker<UncountedCallArgsChecker>();
193 bool ento::shouldRegisterUncountedCallArgsChecker(
const CheckerManager &) {