blob: 6184a77cf39104df2628705972bd17257a5d6afc [file] [log] [blame]
Zhongxing Xu259d4642009-11-04 01:43:07 +00001//=== VLASizeChecker.cpp - Undefined 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 two VLASizeCheckers, a builtin check in GRExprEngine that
11// performs checks for declaration of VLA of undefined or zero size.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Analysis/PathSensitive/Checkers/VLASizeChecker.h"
16#include "clang/Analysis/PathSensitive/GRExprEngine.h"
17#include "clang/Analysis/PathSensitive/BugReporter.h"
18
19using namespace clang;
20
21void *UndefSizedVLAChecker::getTag() {
22 static int x = 0;
23 return &x;
24}
25
26ExplodedNode *UndefSizedVLAChecker::CheckType(QualType T, ExplodedNode *Pred,
27 const GRState *state,
28 Stmt *S, GRExprEngine &Eng) {
29 GRStmtNodeBuilder &Builder = Eng.getBuilder();
30 BugReporter &BR = Eng.getBugReporter();
31
32 if (VariableArrayType* VLA = dyn_cast<VariableArrayType>(T)) {
33 // FIXME: Handle multi-dimensional VLAs.
34 Expr* SE = VLA->getSizeExpr();
35 SVal Size_untested = state->getSVal(SE);
36
37 if (Size_untested.isUndef()) {
38 if (ExplodedNode* N = Builder.generateNode(S, state, Pred)) {
39 N->markAsSink();
40 if (!BT)
Ted Kremenek2980b972009-11-06 00:44:32 +000041 BT = new BuiltinBug("Declared variable-length array (VLA) uses a "
42 "garbage value as its size");
Zhongxing Xu259d4642009-11-04 01:43:07 +000043
44 EnhancedBugReport *R =
45 new EnhancedBugReport(*BT, BT->getName().c_str(), N);
46 R->addRange(SE->getSourceRange());
47 R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, SE);
48 BR.EmitReport(R);
49 }
50 return 0;
51 }
52 }
53 return Pred;
54}
55
56void *ZeroSizedVLAChecker::getTag() {
57 static int x;
58 return &x;
59}
60
61ExplodedNode *ZeroSizedVLAChecker::CheckType(QualType T, ExplodedNode *Pred,
62 const GRState *state, Stmt *S,
63 GRExprEngine &Eng) {
64 GRStmtNodeBuilder &Builder = Eng.getBuilder();
65 BugReporter &BR = Eng.getBugReporter();
66
67 if (VariableArrayType* VLA = dyn_cast<VariableArrayType>(T)) {
68 // FIXME: Handle multi-dimensional VLAs.
69 Expr* SE = VLA->getSizeExpr();
70 SVal Size_untested = state->getSVal(SE);
71
72 DefinedOrUnknownSVal *Size = dyn_cast<DefinedOrUnknownSVal>(&Size_untested);
73 // Undefined size is checked in another checker.
74 if (!Size)
75 return Pred;
76
77 const GRState *zeroState = state->Assume(*Size, false);
78 state = state->Assume(*Size, true);
79
80 if (zeroState && !state) {
81 if (ExplodedNode* N = Builder.generateNode(S, zeroState, Pred)) {
82 N->markAsSink();
83 if (!BT)
Ted Kremenekc92ff052009-11-05 08:30:12 +000084 BT = new BugType("Declared variable-length array (VLA) has zero size",
Zhongxing Xu259d4642009-11-04 01:43:07 +000085 "Logic error");
86
87 EnhancedBugReport *R =
88 new EnhancedBugReport(*BT, BT->getName().c_str(), N);
89 R->addRange(SE->getSourceRange());
90 R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, SE);
91 BR.EmitReport(R);
92 }
93 }
94 if (!state)
95 return 0;
96
97 return Builder.generateNode(S, state, Pred);
98 }
99 else
100 return Pred;
101}
102