blob: ef7da61901a214997beac26576daedb5a540087e [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 Kremenekd86caaa2009-10-30 17:28:40 +000015#include "clang/Analysis/PathSensitive/Checkers/NullDerefChecker.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)
54 BT = new BuiltinBug(NULL, "Null dereference",
55 "Dereference of null pointer");
56
57 EnhancedBugReport *R =
58 new EnhancedBugReport(*BT, BT->getDescription().c_str(), N);
59
60 R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
61 bugreporter::GetDerefExpr(N));
62
63 BR.EmitReport(R);
64
65 return 0;
66 } else // Implicit null case.
67 ImplicitNullDerefNodes.push_back(N);
68 }
69 }
70
71 if (!NotNullState)
72 return 0;
73
74 return Builder.generateNode(S, NotNullState, Pred,
75 ProgramPoint::PostLocationChecksSucceedKind);
76}