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.";
64 const auto *ElemLR = dyn_cast<ElementRegion>(LR);
65 const auto *ElemRR = dyn_cast<ElementRegion>(RR);
68 if (ElemLR && ElemLR->getSuperRegion() == RR)
71 if (ElemRR && ElemRR->getSuperRegion() == LR)
77 if (ElemLR && ElemRR) {
78 const MemRegion *SuperLR = ElemLR->getSuperRegion();
79 const MemRegion *SuperRR = ElemRR->getSuperRegion();
80 if (SuperLR == SuperRR)
83 if (isa<SymbolicRegion>(SuperLR) || isa<SymbolicRegion>(SuperRR))
85 if (
const auto *SuperDLR = dyn_cast<DeclRegion>(SuperLR))
86 DiffDeclL = SuperDLR->getDecl();
87 if (
const auto *SuperDRR = dyn_cast<DeclRegion>(SuperRR))
88 DiffDeclR = SuperDRR->getDecl();
93 std::make_unique<PathSensitiveBugReport>(BT, Msg_MemRegionDifferent, N);
99 if (DiffDeclL != DiffDeclR) {
100 auto AddNote = [&R, &
C](
const ValueDecl *
D, StringRef SideStr) {
102 std::string Msg = llvm::formatv(
103 "{0} at the {1}-hand side of subtraction",
104 D->getType()->isArrayType() ?
"Array" :
"Object", SideStr);
105 R->addNote(Msg, {
D,
C.getSourceManager()});
108 AddNote(DiffDeclL,
"left");
109 AddNote(DiffDeclR,
"right");
111 C.emitReport(std::move(R));
119bool 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...
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.