blob: 8984a5f39058a878c789171d3119593eebd56ddf [file] [log] [blame]
Zhongxing Xu5206f0b2009-11-03 12:13:38 +00001//=== ZeroSizedVLAChecker.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 ZeorSizedVLAChecker, a builtin check in GRExprEngine that
11// performs checks for declaration of VLA of zero size.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Analysis/PathSensitive/Checkers/ZeroSizedVLAChecker.h"
16#include "clang/Analysis/PathSensitive/GRExprEngine.h"
17#include "clang/Analysis/PathSensitive/BugReporter.h"
18
19using namespace clang;
20
21void *ZeroSizedVLAChecker::getTag() {
22 static int x;
23 return &x;
24}
25
26ExplodedNode *ZeroSizedVLAChecker::CheckType(QualType T, ExplodedNode *Pred,
27 const GRState *state, Stmt *S,
28 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 DefinedOrUnknownSVal *Size = dyn_cast<DefinedOrUnknownSVal>(&Size_untested);
38 // Undefined size is checked in another checker.
39 if (!Size)
40 return Pred;
41
42 const GRState *zeroState = state->Assume(*Size, false);
43 state = state->Assume(*Size, true);
44
45 if (zeroState && !state) {
46 if (ExplodedNode* N = Builder.generateNode(S, zeroState, Pred)) {
47 N->markAsSink();
48 if (!BT)
49 BT = new BugType("Declare variable-length array (VLA) of zero size",
50 "Logic error");
51
52 EnhancedBugReport *R =
53 new EnhancedBugReport(*BT, BT->getName().c_str(), N);
54 R->addRange(SE->getSourceRange());
55 R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, SE);
56 BR.EmitReport(R);
57 }
58 }
59 if (!state)
60 return 0;
61
62 return Builder.generateNode(S, state, Pred);
63 }
64 else
65 return Pred;
66}