1 //=== PointerSubChecker.cpp - Pointer subtraction checker ------*- C++ -*--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This files defines PointerSubChecker, a builtin checker that checks for
11 // pointer subtractions on two pointers pointing to different memory chunks.
12 // This check corresponds to CWE-469.
14 //===----------------------------------------------------------------------===//
16 #include "InternalChecks.h"
17 #include "clang/StaticAnalyzer/BugReporter/BugType.h"
18 #include "clang/StaticAnalyzer/PathSensitive/CheckerVisitor.h"
20 using namespace clang
;
24 class PointerSubChecker
25 : public CheckerVisitor
<PointerSubChecker
> {
28 PointerSubChecker() : BT(0) {}
29 static void *getTag();
30 void PreVisitBinaryOperator(CheckerContext
&C
, const BinaryOperator
*B
);
34 void *PointerSubChecker::getTag() {
39 void PointerSubChecker::PreVisitBinaryOperator(CheckerContext
&C
,
40 const BinaryOperator
*B
) {
41 // When doing pointer subtraction, if the two pointers do not point to the
42 // same memory chunk, emit a warning.
43 if (B
->getOpcode() != BO_Sub
)
46 const GRState
*state
= C
.getState();
47 SVal LV
= state
->getSVal(B
->getLHS());
48 SVal RV
= state
->getSVal(B
->getRHS());
50 const MemRegion
*LR
= LV
.getAsRegion();
51 const MemRegion
*RR
= RV
.getAsRegion();
56 const MemRegion
*BaseLR
= LR
->getBaseRegion();
57 const MemRegion
*BaseRR
= RR
->getBaseRegion();
62 // Allow arithmetic on different symbolic regions.
63 if (isa
<SymbolicRegion
>(BaseLR
) || isa
<SymbolicRegion
>(BaseRR
))
66 if (ExplodedNode
*N
= C
.generateNode()) {
68 BT
= new BuiltinBug("Pointer subtraction",
69 "Subtraction of two pointers that do not point to "
70 "the same memory chunk may cause incorrect result.");
71 RangedBugReport
*R
= new RangedBugReport(*BT
, BT
->getDescription(), N
);
72 R
->addRange(B
->getSourceRange());
77 void ento::RegisterPointerSubChecker(ExprEngine
&Eng
) {
78 Eng
.registerCheck(new PointerSubChecker());