blob: b7233419ef366cefa39b075b1b449681eb14353e [file] [log] [blame]
Ted Kremenekbc3a0212009-10-30 17:24:47 +00001//== NullDerefChecker.cpp - Null dereference checker ------------*- C++ -*--==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This defines NullDerefChecker, a builtin check in GRExprEngine that performs
11// checks for null pointers at loads and stores.
12//
13//===----------------------------------------------------------------------===//
14
Ted Kremenekdc998c12009-11-03 18:41:06 +000015#include "clang/Analysis/PathSensitive/Checkers/DereferenceChecker.h"
Ted Kremenekbc3a0212009-10-30 17:24:47 +000016#include "clang/Analysis/PathSensitive/GRExprEngine.h"
17#include "clang/Analysis/PathSensitive/BugReporter.h"
18
19using namespace clang;
20
21void *NullDerefChecker::getTag() {
22 static int x = 0;
23 return &x;
24}
25
26ExplodedNode *NullDerefChecker::CheckLocation(const Stmt *S, ExplodedNode *Pred,
27 const GRState *state, SVal V,
28 GRExprEngine &Eng) {
29 Loc *LV = dyn_cast<Loc>(&V);
30
31 // If the value is not a location, don't touch the node.
32 if (!LV)
33 return Pred;
34
35 const GRState *NotNullState = state->Assume(*LV, true);
36 const GRState *NullState = state->Assume(*LV, false);
37
38 GRStmtNodeBuilder &Builder = Eng.getBuilder();
39 BugReporter &BR = Eng.getBugReporter();
40
41 // The explicit NULL case.
42 if (NullState) {
43 // Use the GDM to mark in the state what lval was null.
44 const SVal *PersistentLV = Eng.getBasicVals().getPersistentSVal(*LV);
45 NullState = NullState->set<GRState::NullDerefTag>(PersistentLV);
46
47 ExplodedNode *N = Builder.generateNode(S, NullState, Pred,
Zhongxing Xuff041742009-10-31 03:36:08 +000048 ProgramPoint::PostNullCheckFailedKind);
Ted Kremenekbc3a0212009-10-30 17:24:47 +000049 if (N) {
50 N->markAsSink();
51
52 if (!NotNullState) { // Explicit null case.
53 if (!BT)
Ted Kremenek2c791bd2009-11-06 00:44:32 +000054 BT = new BuiltinBug("Null dereference","Dereference of null pointer");
Ted Kremenekbc3a0212009-10-30 17:24:47 +000055
56 EnhancedBugReport *R =
57 new EnhancedBugReport(*BT, BT->getDescription().c_str(), N);
Ted Kremenek2c791bd2009-11-06 00:44:32 +000058
Ted Kremenekbc3a0212009-10-30 17:24:47 +000059 R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
60 bugreporter::GetDerefExpr(N));
61
62 BR.EmitReport(R);
63
64 return 0;
65 } else // Implicit null case.
66 ImplicitNullDerefNodes.push_back(N);
67 }
68 }
69
70 if (!NotNullState)
71 return 0;
72
73 return Builder.generateNode(S, NotNullState, Pred,
74 ProgramPoint::PostLocationChecksSucceedKind);
75}
Ted Kremenekdc998c12009-11-03 18:41:06 +000076
77
78void *UndefDerefChecker::getTag() {
79 static int x = 0;
80 return &x;
81}
82
83ExplodedNode *UndefDerefChecker::CheckLocation(const Stmt *S,
84 ExplodedNode *Pred,
85 const GRState *state, SVal V,
86 GRExprEngine &Eng) {
87 GRStmtNodeBuilder &Builder = Eng.getBuilder();
88 BugReporter &BR = Eng.getBugReporter();
89
90 if (V.isUndef()) {
91 ExplodedNode *N = Builder.generateNode(S, state, Pred,
92 ProgramPoint::PostUndefLocationCheckFailedKind);
93 if (N) {
94 N->markAsSink();
95
96 if (!BT)
97 BT = new BuiltinBug(0, "Undefined dereference",
98 "Dereference of undefined pointer value");
99
100 EnhancedBugReport *R =
101 new EnhancedBugReport(*BT, BT->getDescription().c_str(), N);
102 R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
103 bugreporter::GetDerefExpr(N));
104 BR.EmitReport(R);
105 }
106 return 0;
107 }
108
109 return Pred;
110}
111