21#include "llvm/ADT/StringRef.h"
22#include "llvm/Support/FormatVariadic.h"
28class PointerSubChecker
29 :
public Checker< check::PreStmt<BinaryOperator> > {
30 const BugType BT{
this,
"Pointer subtraction"};
31 const llvm::StringLiteral Msg_MemRegionDifferent =
32 "Subtraction of two pointers that do not point into the same array "
33 "is undefined behavior.";
68 const auto *ElemLR = dyn_cast<ElementRegion>(LR);
69 const auto *ElemRR = dyn_cast<ElementRegion>(RR);
72 if (ElemLR && ElemLR->getSuperRegion() == RR)
75 if (ElemRR && ElemRR->getSuperRegion() == LR)
81 if (ElemLR && ElemRR) {
82 const MemRegion *SuperLR = ElemLR->getSuperRegion();
83 const MemRegion *SuperRR = ElemRR->getSuperRegion();
84 if (SuperLR == SuperRR)
87 if (isa<SymbolicRegion>(SuperLR) || isa<SymbolicRegion>(SuperRR))
89 if (
const auto *SuperDLR = dyn_cast<DeclRegion>(SuperLR))
90 DiffDeclL = SuperDLR->getDecl();
91 if (
const auto *SuperDRR = dyn_cast<DeclRegion>(SuperRR))
92 DiffDeclR = SuperDRR->getDecl();
97 std::make_unique<PathSensitiveBugReport>(BT, Msg_MemRegionDifferent, N);
103 if (DiffDeclL != DiffDeclR) {
104 auto AddNote = [&R, &
C](
const ValueDecl *
D, StringRef SideStr) {
106 std::string Msg = llvm::formatv(
107 "{0} at the {1}-hand side of subtraction",
108 D->getType()->isArrayType() ?
"Array" :
"Object", SideStr);
109 R->addNote(Msg, {
D,
C.getSourceManager()});
112 AddNote(DiffDeclL,
"left");
113 AddNote(DiffDeclR,
"right");
115 C.emitReport(std::move(R));
123bool ento::shouldRegisterPointerSubChecker(
const CheckerManager &mgr) {
A builtin binary operation expression such as "x + y" or "x <= y".
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool isPointerType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
MemRegion - The root abstract class for all memory regions.
const SymbolicRegion * getSymbolicBase() const
If this is a symbolic region, returns the region.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
const MemRegion * getAsRegion() const
The JSON file list parser is used to communicate input to InstallAPI.