void MyChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) { const Expr *Arg = Call.getArgExpr(0); if (!Arg) return; QualType T = Arg->getType(); if (T->isPointerType()) { const auto *PT = T->getPointeeType()->getAs(); if (PT && PT->getPointeeType().isNull()) { PathDiagnosticLocation DLoc(Call.getOriginExpr(), C.getSourceManager(), C.getLangOpts()); auto Report = std::make_unique ( *NullabilityChecker, "Nullability mismatch", DLoc); Report->addRange(Arg->getSourceRange()); Report->addRange(Call.getOriginExpr()->getSourceRange()); C.emitReport(std::move(Report)); C.generateErrorNode(); } } }
void MyChecker::checkBinaryOperator(const BinaryOperator *BO, CheckerContext &C) const { const Expr *LHS = BO->getLHS(); const Expr *RHS = BO->getRHS(); if (BO->getOpcode() == BO_Assign) { const VarDecl *VD = BO->getLHS()->getReferencedDeclOfCallee(); if (VD) { QualType T = VD->getType(); if (T->isIntegerType()) { const auto DL = C.getLocation(BO->getOperatorLoc()); SVal LeftV = C.getSVal(LHS, DL); SVal RightV = C.getSVal(RHS, DL); if (LeftV.isUnknownOrUndef() || RightV.isUnknownOrUndef()) return; DefinedOrUnknownSVal Result = evalBinOp(C, BO->getOpcode(), LeftV, RightV, T); ProgramStateRef State = C.getState(); State = State->assume(Result, true); if (!State) C.generateErrorNode(); } } } }This code demonstrates how to use generateErrorNode to create an error node when there is an integer overflow in a C++ program. The function checks if the binary operator is an assignment, if it is then it checks if the left-hand side is an integer type. If it is, it evaluates the binary operation using evalBinOp, and then assumes the result is true using the assume function. If the result cannot be assumed to be true, it calls generateErrorNode to create an error node at the location of the assignment. Package/Library: Clang static analyzer library.