blob: 35ca0c5dfb6db3fa97c261ab5f08d671f40dfdbf [file] [log] [blame]
Ted Kremenek78d46242008-07-22 16:21:24 +00001//=-- GRExprEngineInternalChecks.cpp - Builtin GRExprEngine Checks---*- 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 file defines the BugType classes used by GRExprEngine to report
11// bugs derived from builtin checks in the path-sensitive engine.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Analysis/PathSensitive/BugReporter.h"
16#include "clang/Analysis/PathSensitive/GRExprEngine.h"
Ted Kremenekc26a8b02009-07-22 21:46:56 +000017#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
Ted Kremenekdd986cc2009-05-07 00:45:33 +000018#include "clang/Analysis/PathDiagnostic.h"
Ted Kremenek8aed8062008-10-31 00:13:20 +000019#include "clang/Basic/SourceManager.h"
Ted Kremenek78d46242008-07-22 16:21:24 +000020#include "llvm/Support/Compiler.h"
Ted Kremenekad51a602008-10-31 00:18:30 +000021#include "llvm/Support/raw_ostream.h"
Ted Kremenek78d46242008-07-22 16:21:24 +000022
23using namespace clang;
Ted Kremenek53500662009-07-22 17:55:28 +000024using namespace clang::bugreporter;
Ted Kremenek78d46242008-07-22 16:21:24 +000025
26//===----------------------------------------------------------------------===//
27// Utility functions.
28//===----------------------------------------------------------------------===//
29
30template <typename ITERATOR> inline
Zhongxing Xuc5619d92009-08-06 01:32:16 +000031ExplodedNode* GetNode(ITERATOR I) {
Ted Kremenek78d46242008-07-22 16:21:24 +000032 return *I;
33}
34
35template <> inline
Zhongxing Xuc5619d92009-08-06 01:32:16 +000036ExplodedNode* GetNode(GRExprEngine::undef_arg_iterator I) {
Ted Kremenek78d46242008-07-22 16:21:24 +000037 return I->first;
38}
39
40//===----------------------------------------------------------------------===//
41// Bug Descriptions.
42//===----------------------------------------------------------------------===//
43
44namespace {
Ted Kremenekdd986cc2009-05-07 00:45:33 +000045
Ted Kremenek0c313172009-05-13 19:16:35 +000046class VISIBILITY_HIDDEN BuiltinBugReport : public RangedBugReport {
Ted Kremenekdd986cc2009-05-07 00:45:33 +000047public:
48 BuiltinBugReport(BugType& bt, const char* desc,
Zhongxing Xuc5619d92009-08-06 01:32:16 +000049 ExplodedNode *n)
Ted Kremenek0c313172009-05-13 19:16:35 +000050 : RangedBugReport(bt, desc, n) {}
Ted Kremenekdd986cc2009-05-07 00:45:33 +000051
Ted Kremenek85ac9342009-05-15 05:25:09 +000052 BuiltinBugReport(BugType& bt, const char *shortDesc, const char *desc,
Zhongxing Xuc5619d92009-08-06 01:32:16 +000053 ExplodedNode *n)
Ted Kremenek85ac9342009-05-15 05:25:09 +000054 : RangedBugReport(bt, shortDesc, desc, n) {}
55
Ted Kremenekdd986cc2009-05-07 00:45:33 +000056 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +000057 const ExplodedNode* N);
Ted Kremenekdd986cc2009-05-07 00:45:33 +000058};
59
Ted Kremenekcf118d42009-02-04 23:49:09 +000060class VISIBILITY_HIDDEN BuiltinBug : public BugType {
61 GRExprEngine &Eng;
Ted Kremenek159d2482008-12-09 00:44:16 +000062protected:
Ted Kremenekcf118d42009-02-04 23:49:09 +000063 const std::string desc;
Ted Kremenek78d46242008-07-22 16:21:24 +000064public:
Ted Kremenekcf118d42009-02-04 23:49:09 +000065 BuiltinBug(GRExprEngine *eng, const char* n, const char* d)
Ted Kremenek0c313172009-05-13 19:16:35 +000066 : BugType(n, "Logic errors"), Eng(*eng), desc(d) {}
Ted Kremenekcf118d42009-02-04 23:49:09 +000067
68 BuiltinBug(GRExprEngine *eng, const char* n)
Ted Kremenek0c313172009-05-13 19:16:35 +000069 : BugType(n, "Logic errors"), Eng(*eng), desc(n) {}
Ted Kremenek22bda882008-07-31 20:31:27 +000070
Ted Kremenekcf118d42009-02-04 23:49:09 +000071 virtual void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) = 0;
72
73 void FlushReports(BugReporter& BR) { FlushReportsImpl(BR, Eng); }
Ted Kremenek78d46242008-07-22 16:21:24 +000074
Ted Kremenekdd986cc2009-05-07 00:45:33 +000075 virtual void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +000076 const ExplodedNode* N,
Ted Kremenekdd986cc2009-05-07 00:45:33 +000077 BuiltinBugReport *R) {}
78
79 template <typename ITER> void Emit(BugReporter& BR, ITER I, ITER E);
Ted Kremenek78d46242008-07-22 16:21:24 +000080};
81
Ted Kremenekdd986cc2009-05-07 00:45:33 +000082
83template <typename ITER>
84void BuiltinBug::Emit(BugReporter& BR, ITER I, ITER E) {
85 for (; I != E; ++I) BR.EmitReport(new BuiltinBugReport(*this, desc.c_str(),
86 GetNode(I)));
87}
88
89void BuiltinBugReport::registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +000090 const ExplodedNode* N) {
Ted Kremenekdd986cc2009-05-07 00:45:33 +000091 static_cast<BuiltinBug&>(getBugType()).registerInitialVisitors(BRC, N, this);
92}
93
Ted Kremenek78d46242008-07-22 16:21:24 +000094class VISIBILITY_HIDDEN NullDeref : public BuiltinBug {
95public:
Ted Kremenekcf118d42009-02-04 23:49:09 +000096 NullDeref(GRExprEngine* eng)
Ted Kremenek0fa96542009-04-07 04:54:31 +000097 : BuiltinBug(eng,"Null dereference", "Dereference of null pointer") {}
Ted Kremenek78d46242008-07-22 16:21:24 +000098
Ted Kremenekcf118d42009-02-04 23:49:09 +000099 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000100 Emit(BR, Eng.null_derefs_begin(), Eng.null_derefs_end());
101 }
Ted Kremenekdd986cc2009-05-07 00:45:33 +0000102
103 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000104 const ExplodedNode* N,
Ted Kremenekdd986cc2009-05-07 00:45:33 +0000105 BuiltinBugReport *R) {
Ted Kremenek85ac9342009-05-15 05:25:09 +0000106 registerTrackNullOrUndefValue(BRC, GetDerefExpr(N), N);
Ted Kremenekdd986cc2009-05-07 00:45:33 +0000107 }
Ted Kremenek78d46242008-07-22 16:21:24 +0000108};
109
Ted Kremenek0c313172009-05-13 19:16:35 +0000110class VISIBILITY_HIDDEN NilReceiverStructRet : public BuiltinBug {
Ted Kremenek21fe8372009-02-19 04:06:22 +0000111public:
112 NilReceiverStructRet(GRExprEngine* eng) :
Ted Kremenek0c313172009-05-13 19:16:35 +0000113 BuiltinBug(eng, "'nil' receiver with struct return type") {}
Ted Kremenek21fe8372009-02-19 04:06:22 +0000114
Ted Kremenek0c313172009-05-13 19:16:35 +0000115 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenek21fe8372009-02-19 04:06:22 +0000116 for (GRExprEngine::nil_receiver_struct_ret_iterator
117 I=Eng.nil_receiver_struct_ret_begin(),
118 E=Eng.nil_receiver_struct_ret_end(); I!=E; ++I) {
119
120 std::string sbuf;
121 llvm::raw_string_ostream os(sbuf);
122 PostStmt P = cast<PostStmt>((*I)->getLocation());
Ted Kremenek5f85e172009-07-22 22:35:28 +0000123 const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(P.getStmt());
Ted Kremenek21fe8372009-02-19 04:06:22 +0000124 os << "The receiver in the message expression is 'nil' and results in the"
125 " returned value (of type '"
126 << ME->getType().getAsString()
127 << "') to be garbage or otherwise undefined.";
128
Ted Kremenek0c313172009-05-13 19:16:35 +0000129 BuiltinBugReport *R = new BuiltinBugReport(*this, os.str().c_str(), *I);
Ted Kremenek21fe8372009-02-19 04:06:22 +0000130 R->addRange(ME->getReceiver()->getSourceRange());
131 BR.EmitReport(R);
132 }
133 }
Ted Kremenek0c313172009-05-13 19:16:35 +0000134
135 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000136 const ExplodedNode* N,
Ted Kremenek0c313172009-05-13 19:16:35 +0000137 BuiltinBugReport *R) {
Ted Kremenek85ac9342009-05-15 05:25:09 +0000138 registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
Ted Kremenek0c313172009-05-13 19:16:35 +0000139 }
Ted Kremenek21fe8372009-02-19 04:06:22 +0000140};
Ted Kremenek899b3de2009-04-08 03:07:17 +0000141
Ted Kremenek0c313172009-05-13 19:16:35 +0000142class VISIBILITY_HIDDEN NilReceiverLargerThanVoidPtrRet : public BuiltinBug {
Ted Kremenek899b3de2009-04-08 03:07:17 +0000143public:
144 NilReceiverLargerThanVoidPtrRet(GRExprEngine* eng) :
Ted Kremenek0c313172009-05-13 19:16:35 +0000145 BuiltinBug(eng,
146 "'nil' receiver with return type larger than sizeof(void *)") {}
Ted Kremenek899b3de2009-04-08 03:07:17 +0000147
Ted Kremenek0c313172009-05-13 19:16:35 +0000148 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenek899b3de2009-04-08 03:07:17 +0000149 for (GRExprEngine::nil_receiver_larger_than_voidptr_ret_iterator
150 I=Eng.nil_receiver_larger_than_voidptr_ret_begin(),
151 E=Eng.nil_receiver_larger_than_voidptr_ret_end(); I!=E; ++I) {
152
153 std::string sbuf;
154 llvm::raw_string_ostream os(sbuf);
155 PostStmt P = cast<PostStmt>((*I)->getLocation());
Ted Kremenek5f85e172009-07-22 22:35:28 +0000156 const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(P.getStmt());
Ted Kremenek899b3de2009-04-08 03:07:17 +0000157 os << "The receiver in the message expression is 'nil' and results in the"
158 " returned value (of type '"
159 << ME->getType().getAsString()
160 << "' and of size "
161 << Eng.getContext().getTypeSize(ME->getType()) / 8
162 << " bytes) to be garbage or otherwise undefined.";
163
Ted Kremenek0c313172009-05-13 19:16:35 +0000164 BuiltinBugReport *R = new BuiltinBugReport(*this, os.str().c_str(), *I);
Ted Kremenek899b3de2009-04-08 03:07:17 +0000165 R->addRange(ME->getReceiver()->getSourceRange());
166 BR.EmitReport(R);
167 }
Ted Kremenek0c313172009-05-13 19:16:35 +0000168 }
169 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000170 const ExplodedNode* N,
Ted Kremenek0c313172009-05-13 19:16:35 +0000171 BuiltinBugReport *R) {
Ted Kremenek85ac9342009-05-15 05:25:09 +0000172 registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
Ted Kremenek899b3de2009-04-08 03:07:17 +0000173 }
174};
Ted Kremenek21fe8372009-02-19 04:06:22 +0000175
Ted Kremenek78d46242008-07-22 16:21:24 +0000176class VISIBILITY_HIDDEN UndefinedDeref : public BuiltinBug {
177public:
Ted Kremenekcf118d42009-02-04 23:49:09 +0000178 UndefinedDeref(GRExprEngine* eng)
Ted Kremenek17a8e072009-03-01 05:43:22 +0000179 : BuiltinBug(eng,"Dereference of undefined pointer value") {}
Ted Kremenek78d46242008-07-22 16:21:24 +0000180
Ted Kremenekcf118d42009-02-04 23:49:09 +0000181 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000182 Emit(BR, Eng.undef_derefs_begin(), Eng.undef_derefs_end());
183 }
Ted Kremenek0c313172009-05-13 19:16:35 +0000184
185 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000186 const ExplodedNode* N,
Ted Kremenek0c313172009-05-13 19:16:35 +0000187 BuiltinBugReport *R) {
Ted Kremenek85ac9342009-05-15 05:25:09 +0000188 registerTrackNullOrUndefValue(BRC, GetDerefExpr(N), N);
Ted Kremenek0c313172009-05-13 19:16:35 +0000189 }
Ted Kremenek78d46242008-07-22 16:21:24 +0000190};
191
192class VISIBILITY_HIDDEN DivZero : public BuiltinBug {
193public:
Ted Kremenekcf118d42009-02-04 23:49:09 +0000194 DivZero(GRExprEngine* eng)
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000195 : BuiltinBug(eng,"Division-by-zero",
196 "Division by zero or undefined value.") {}
Ted Kremenek78d46242008-07-22 16:21:24 +0000197
Ted Kremenekcf118d42009-02-04 23:49:09 +0000198 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000199 Emit(BR, Eng.explicit_bad_divides_begin(), Eng.explicit_bad_divides_end());
200 }
Ted Kremenek85ac9342009-05-15 05:25:09 +0000201
202 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000203 const ExplodedNode* N,
Ted Kremenek85ac9342009-05-15 05:25:09 +0000204 BuiltinBugReport *R) {
205 registerTrackNullOrUndefValue(BRC, GetDenomExpr(N), N);
206 }
Ted Kremenek78d46242008-07-22 16:21:24 +0000207};
208
209class VISIBILITY_HIDDEN UndefResult : public BuiltinBug {
210public:
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000211 UndefResult(GRExprEngine* eng) : BuiltinBug(eng,"Undefined result",
Ted Kremenek78d46242008-07-22 16:21:24 +0000212 "Result of operation is undefined.") {}
213
Ted Kremenekcf118d42009-02-04 23:49:09 +0000214 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000215 Emit(BR, Eng.undef_results_begin(), Eng.undef_results_end());
216 }
217};
218
219class VISIBILITY_HIDDEN BadCall : public BuiltinBug {
220public:
Ted Kremenekcf118d42009-02-04 23:49:09 +0000221 BadCall(GRExprEngine *eng)
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000222 : BuiltinBug(eng, "Invalid function call",
Ted Kremenek17a8e072009-03-01 05:43:22 +0000223 "Called function pointer is a null or undefined pointer value") {}
Ted Kremenek78d46242008-07-22 16:21:24 +0000224
Ted Kremenekcf118d42009-02-04 23:49:09 +0000225 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000226 Emit(BR, Eng.bad_calls_begin(), Eng.bad_calls_end());
227 }
Ted Kremenek85ac9342009-05-15 05:25:09 +0000228
229 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000230 const ExplodedNode* N,
Ted Kremenek85ac9342009-05-15 05:25:09 +0000231 BuiltinBugReport *R) {
232 registerTrackNullOrUndefValue(BRC, GetCalleeExpr(N), N);
233 }
234};
235
236
237class VISIBILITY_HIDDEN ArgReport : public BuiltinBugReport {
238 const Stmt *Arg;
239public:
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000240 ArgReport(BugType& bt, const char* desc, ExplodedNode *n,
Ted Kremenek85ac9342009-05-15 05:25:09 +0000241 const Stmt *arg)
242 : BuiltinBugReport(bt, desc, n), Arg(arg) {}
243
244 ArgReport(BugType& bt, const char *shortDesc, const char *desc,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000245 ExplodedNode *n, const Stmt *arg)
Ted Kremenek85ac9342009-05-15 05:25:09 +0000246 : BuiltinBugReport(bt, shortDesc, desc, n), Arg(arg) {}
247
Zhongxing Xu9a5bca32009-08-29 02:11:01 +0000248 const Stmt *getArg() const { return Arg; }
249
250 void registerInitialVisitors(BugReporterContext& BRC,
251 const ExplodedNode* N) {
252 registerTrackNullOrUndefValue(BRC, getArg(), N);
253 }
Ted Kremenek78d46242008-07-22 16:21:24 +0000254};
255
256class VISIBILITY_HIDDEN BadArg : public BuiltinBug {
Ted Kremenek85ac9342009-05-15 05:25:09 +0000257public:
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000258 BadArg(GRExprEngine* eng) : BuiltinBug(eng,"Uninitialized argument",
Ted Kremenek17a8e072009-03-01 05:43:22 +0000259 "Pass-by-value argument in function call is undefined.") {}
Ted Kremenek78d46242008-07-22 16:21:24 +0000260
Ted Kremenekcf118d42009-02-04 23:49:09 +0000261 BadArg(GRExprEngine* eng, const char* d)
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000262 : BuiltinBug(eng,"Uninitialized argument", d) {}
Ted Kremenek78d46242008-07-22 16:21:24 +0000263
Ted Kremenekcf118d42009-02-04 23:49:09 +0000264 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000265 for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
266 E = Eng.undef_arg_end(); I!=E; ++I) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000267 // Generate a report for this bug.
Ted Kremenek85ac9342009-05-15 05:25:09 +0000268 ArgReport *report = new ArgReport(*this, desc.c_str(), I->first,
269 I->second);
Ted Kremenekcf118d42009-02-04 23:49:09 +0000270 report->addRange(I->second->getSourceRange());
271 BR.EmitReport(report);
Ted Kremenek78d46242008-07-22 16:21:24 +0000272 }
273 }
Ted Kremenek85ac9342009-05-15 05:25:09 +0000274
275 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000276 const ExplodedNode* N,
Ted Kremenek85ac9342009-05-15 05:25:09 +0000277 BuiltinBugReport *R) {
278 registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
279 N);
280 }
Ted Kremenek78d46242008-07-22 16:21:24 +0000281};
282
283class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
284public:
Ted Kremenekcf118d42009-02-04 23:49:09 +0000285 BadMsgExprArg(GRExprEngine* eng)
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000286 : BadArg(eng,"Pass-by-value argument in message expression is undefined"){}
Ted Kremenek78d46242008-07-22 16:21:24 +0000287
Ted Kremenekcf118d42009-02-04 23:49:09 +0000288 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000289 for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
Ted Kremenekcf118d42009-02-04 23:49:09 +0000290 E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000291 // Generate a report for this bug.
Ted Kremenek85ac9342009-05-15 05:25:09 +0000292 ArgReport *report = new ArgReport(*this, desc.c_str(), I->first,
293 I->second);
Ted Kremenekcf118d42009-02-04 23:49:09 +0000294 report->addRange(I->second->getSourceRange());
295 BR.EmitReport(report);
Ted Kremenek78d46242008-07-22 16:21:24 +0000296 }
Ted Kremenek85ac9342009-05-15 05:25:09 +0000297 }
Ted Kremenek78d46242008-07-22 16:21:24 +0000298};
299
300class VISIBILITY_HIDDEN BadReceiver : public BuiltinBug {
301public:
Ted Kremenekcf118d42009-02-04 23:49:09 +0000302 BadReceiver(GRExprEngine* eng)
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000303 : BuiltinBug(eng,"Uninitialized receiver",
304 "Receiver in message expression is an uninitialized value") {}
Ted Kremenek78d46242008-07-22 16:21:24 +0000305
Ted Kremenekcf118d42009-02-04 23:49:09 +0000306 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenekefd59942008-12-08 22:47:34 +0000307 for (GRExprEngine::ErrorNodes::iterator I=Eng.undef_receivers_begin(),
Ted Kremenek78d46242008-07-22 16:21:24 +0000308 End = Eng.undef_receivers_end(); I!=End; ++I) {
309
310 // Generate a report for this bug.
Ted Kremenek0c313172009-05-13 19:16:35 +0000311 BuiltinBugReport *report = new BuiltinBugReport(*this, desc.c_str(), *I);
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000312 ExplodedNode* N = *I;
Ted Kremenek5f85e172009-07-22 22:35:28 +0000313 const Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
314 const Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
Ted Kremenek78d46242008-07-22 16:21:24 +0000315 assert (E && "Receiver cannot be NULL");
Ted Kremenekcf118d42009-02-04 23:49:09 +0000316 report->addRange(E->getSourceRange());
317 BR.EmitReport(report);
Ted Kremenek0c313172009-05-13 19:16:35 +0000318 }
319 }
Ted Kremenek85ac9342009-05-15 05:25:09 +0000320
Ted Kremenek0c313172009-05-13 19:16:35 +0000321 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000322 const ExplodedNode* N,
Ted Kremenek0c313172009-05-13 19:16:35 +0000323 BuiltinBugReport *R) {
Ted Kremenek85ac9342009-05-15 05:25:09 +0000324 registerTrackNullOrUndefValue(BRC, GetReceiverExpr(N), N);
325 }
Ted Kremenek78d46242008-07-22 16:21:24 +0000326};
Ted Kremenek5917d782008-11-21 00:27:44 +0000327
Ted Kremenek78d46242008-07-22 16:21:24 +0000328class VISIBILITY_HIDDEN RetStack : public BuiltinBug {
329public:
Ted Kremenek17a8e072009-03-01 05:43:22 +0000330 RetStack(GRExprEngine* eng)
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000331 : BuiltinBug(eng, "Return of address to stack-allocated memory") {}
Ted Kremenek78d46242008-07-22 16:21:24 +0000332
Ted Kremenekcf118d42009-02-04 23:49:09 +0000333 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenekb7714b22008-07-30 17:49:12 +0000334 for (GRExprEngine::ret_stackaddr_iterator I=Eng.ret_stackaddr_begin(),
335 End = Eng.ret_stackaddr_end(); I!=End; ++I) {
Ted Kremenek22bda882008-07-31 20:31:27 +0000336
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000337 ExplodedNode* N = *I;
Ted Kremenek5f85e172009-07-22 22:35:28 +0000338 const Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
339 const Expr* E = cast<ReturnStmt>(S)->getRetValue();
340 assert(E && "Return expression cannot be NULL");
Ted Kremenek22bda882008-07-31 20:31:27 +0000341
342 // Get the value associated with E.
Ted Kremenek23ec48c2009-06-18 23:58:37 +0000343 loc::MemRegionVal V = cast<loc::MemRegionVal>(N->getState()->getSVal(E));
Ted Kremenek22bda882008-07-31 20:31:27 +0000344
345 // Generate a report for this bug.
Ted Kremenekad51a602008-10-31 00:18:30 +0000346 std::string buf;
347 llvm::raw_string_ostream os(buf);
Ted Kremenek8aed8062008-10-31 00:13:20 +0000348 SourceRange R;
Ted Kremenek22bda882008-07-31 20:31:27 +0000349
Ted Kremenek8aed8062008-10-31 00:13:20 +0000350 // Check if the region is a compound literal.
351 if (const CompoundLiteralRegion* CR =
352 dyn_cast<CompoundLiteralRegion>(V.getRegion())) {
353
354 const CompoundLiteralExpr* CL = CR->getLiteralExpr();
355 os << "Address of stack memory associated with a compound literal "
356 "declared on line "
Chris Lattnerf7cf85b2009-01-16 07:36:28 +0000357 << BR.getSourceManager()
358 .getInstantiationLineNumber(CL->getLocStart())
Ted Kremenek8aed8062008-10-31 00:13:20 +0000359 << " returned.";
360
361 R = CL->getSourceRange();
362 }
Ted Kremenekde8cd192008-11-02 00:35:25 +0000363 else if (const AllocaRegion* AR = dyn_cast<AllocaRegion>(V.getRegion())) {
364 const Expr* ARE = AR->getExpr();
365 SourceLocation L = ARE->getLocStart();
366 R = ARE->getSourceRange();
367
368 os << "Address of stack memory allocated by call to alloca() on line "
Chris Lattnerf7cf85b2009-01-16 07:36:28 +0000369 << BR.getSourceManager().getInstantiationLineNumber(L)
Ted Kremenekde8cd192008-11-02 00:35:25 +0000370 << " returned.";
371 }
Ted Kremenek8aed8062008-10-31 00:13:20 +0000372 else {
373 os << "Address of stack memory associated with local variable '"
374 << V.getRegion()->getString() << "' returned.";
375 }
Ted Kremenek22bda882008-07-31 20:31:27 +0000376
Ted Kremenekcf118d42009-02-04 23:49:09 +0000377 RangedBugReport *report = new RangedBugReport(*this, os.str().c_str(), N);
378 report->addRange(E->getSourceRange());
379 if (R.isValid()) report->addRange(R);
380 BR.EmitReport(report);
Ted Kremenekb7714b22008-07-30 17:49:12 +0000381 }
Ted Kremenek78d46242008-07-22 16:21:24 +0000382 }
383};
Ted Kremenek5917d782008-11-21 00:27:44 +0000384
385class VISIBILITY_HIDDEN RetUndef : public BuiltinBug {
386public:
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000387 RetUndef(GRExprEngine* eng) : BuiltinBug(eng, "Uninitialized return value",
Ted Kremenek0c313172009-05-13 19:16:35 +0000388 "Uninitialized or undefined value returned to caller.") {}
Ted Kremenek5917d782008-11-21 00:27:44 +0000389
Ted Kremenekcf118d42009-02-04 23:49:09 +0000390 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenek5917d782008-11-21 00:27:44 +0000391 Emit(BR, Eng.ret_undef_begin(), Eng.ret_undef_end());
392 }
Ted Kremenek0c313172009-05-13 19:16:35 +0000393
394 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000395 const ExplodedNode* N,
Ted Kremenek0c313172009-05-13 19:16:35 +0000396 BuiltinBugReport *R) {
Ted Kremenek85ac9342009-05-15 05:25:09 +0000397 registerTrackNullOrUndefValue(BRC, GetRetValExpr(N), N);
398 }
Ted Kremenek5917d782008-11-21 00:27:44 +0000399};
Ted Kremenek78d46242008-07-22 16:21:24 +0000400
401class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
402 struct VISIBILITY_HIDDEN FindUndefExpr {
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000403 GRStateManager& VM;
404 const GRState* St;
Ted Kremenek78d46242008-07-22 16:21:24 +0000405
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000406 FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
Ted Kremenek78d46242008-07-22 16:21:24 +0000407
Ted Kremenekb7714b22008-07-30 17:49:12 +0000408 Expr* FindExpr(Expr* Ex) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000409 if (!MatchesCriteria(Ex))
Ted Kremenekb7714b22008-07-30 17:49:12 +0000410 return 0;
Ted Kremenek78d46242008-07-22 16:21:24 +0000411
Ted Kremenekb7714b22008-07-30 17:49:12 +0000412 for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
Ted Kremenek78d46242008-07-22 16:21:24 +0000413 if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
414 Expr* E2 = FindExpr(ExI);
415 if (E2) return E2;
416 }
417
418 return Ex;
419 }
420
Ted Kremenek23ec48c2009-06-18 23:58:37 +0000421 bool MatchesCriteria(Expr* Ex) { return St->getSVal(Ex).isUndef(); }
Ted Kremenek78d46242008-07-22 16:21:24 +0000422 };
423
424public:
Ted Kremenekcf118d42009-02-04 23:49:09 +0000425 UndefBranch(GRExprEngine *eng)
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000426 : BuiltinBug(eng,"Use of uninitialized value",
Ted Kremenek78d46242008-07-22 16:21:24 +0000427 "Branch condition evaluates to an uninitialized value.") {}
428
Ted Kremenekcf118d42009-02-04 23:49:09 +0000429 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000430 for (GRExprEngine::undef_branch_iterator I=Eng.undef_branches_begin(),
431 E=Eng.undef_branches_end(); I!=E; ++I) {
432
433 // What's going on here: we want to highlight the subexpression of the
434 // condition that is the most likely source of the "uninitialized
435 // branch condition." We do a recursive walk of the condition's
436 // subexpressions and roughly look for the most nested subexpression
437 // that binds to Undefined. We then highlight that expression's range.
Ted Kremenek78d46242008-07-22 16:21:24 +0000438 BlockEdge B = cast<BlockEdge>((*I)->getLocation());
439 Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
440 assert (Ex && "Block must have a terminator.");
441
442 // Get the predecessor node and check if is a PostStmt with the Stmt
443 // being the terminator condition. We want to inspect the state
444 // of that node instead because it will contain main information about
445 // the subexpressions.
Ted Kremenek78d46242008-07-22 16:21:24 +0000446 assert (!(*I)->pred_empty());
447
448 // Note: any predecessor will do. They should have identical state,
449 // since all the BlockEdge did was act as an error sink since the value
450 // had to already be undefined.
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000451 ExplodedNode *N = *(*I)->pred_begin();
Ted Kremenek78d46242008-07-22 16:21:24 +0000452 ProgramPoint P = N->getLocation();
Ted Kremenek4adc81e2008-08-13 04:27:00 +0000453 const GRState* St = (*I)->getState();
Ted Kremenek78d46242008-07-22 16:21:24 +0000454
455 if (PostStmt* PS = dyn_cast<PostStmt>(&P))
456 if (PS->getStmt() == Ex)
457 St = N->getState();
458
459 FindUndefExpr FindIt(Eng.getStateManager(), St);
460 Ex = FindIt.FindExpr(Ex);
461
Ted Kremenek85ac9342009-05-15 05:25:09 +0000462 ArgReport *R = new ArgReport(*this, desc.c_str(), *I, Ex);
Ted Kremenekcf118d42009-02-04 23:49:09 +0000463 R->addRange(Ex->getSourceRange());
464 BR.EmitReport(R);
Ted Kremenek78d46242008-07-22 16:21:24 +0000465 }
466 }
Ted Kremenek85ac9342009-05-15 05:25:09 +0000467
468 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000469 const ExplodedNode* N,
Ted Kremenek85ac9342009-05-15 05:25:09 +0000470 BuiltinBugReport *R) {
471 registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
472 N);
473 }
Ted Kremenek78d46242008-07-22 16:21:24 +0000474};
475
Zhongxing Xu1c0c2332008-11-23 05:52:28 +0000476class VISIBILITY_HIDDEN OutOfBoundMemoryAccess : public BuiltinBug {
477public:
Ted Kremenekcf118d42009-02-04 23:49:09 +0000478 OutOfBoundMemoryAccess(GRExprEngine* eng)
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000479 : BuiltinBug(eng,"Out-of-bounds memory access",
Ted Kremenekcf118d42009-02-04 23:49:09 +0000480 "Load or store into an out-of-bound memory position.") {}
Zhongxing Xu1c0c2332008-11-23 05:52:28 +0000481
Ted Kremenekcf118d42009-02-04 23:49:09 +0000482 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Zhongxing Xu1c0c2332008-11-23 05:52:28 +0000483 Emit(BR, Eng.explicit_oob_memacc_begin(), Eng.explicit_oob_memacc_end());
484 }
485};
Ted Kremenekefd59942008-12-08 22:47:34 +0000486
Ted Kremenek159d2482008-12-09 00:44:16 +0000487class VISIBILITY_HIDDEN BadSizeVLA : public BuiltinBug {
Ted Kremenekefd59942008-12-08 22:47:34 +0000488public:
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000489 BadSizeVLA(GRExprEngine* eng) :
490 BuiltinBug(eng, "Bad variable-length array (VLA) size") {}
Ted Kremenekefd59942008-12-08 22:47:34 +0000491
Ted Kremenekcf118d42009-02-04 23:49:09 +0000492 void FlushReportsImpl(BugReporter& BR, GRExprEngine& Eng) {
Ted Kremenekefd59942008-12-08 22:47:34 +0000493 for (GRExprEngine::ErrorNodes::iterator
Ted Kremenek159d2482008-12-09 00:44:16 +0000494 I = Eng.ExplicitBadSizedVLA.begin(),
495 E = Eng.ExplicitBadSizedVLA.end(); I!=E; ++I) {
496
497 // Determine whether this was a 'zero-sized' VLA or a VLA with an
498 // undefined size.
Zhongxing Xu031ccc02009-08-06 12:48:26 +0000499 ExplodedNode* N = *I;
Ted Kremenek159d2482008-12-09 00:44:16 +0000500 PostStmt PS = cast<PostStmt>(N->getLocation());
Ted Kremenek5f85e172009-07-22 22:35:28 +0000501 const DeclStmt *DS = cast<DeclStmt>(PS.getStmt());
Ted Kremenekefd59942008-12-08 22:47:34 +0000502 VarDecl* VD = cast<VarDecl>(*DS->decl_begin());
503 QualType T = Eng.getContext().getCanonicalType(VD->getType());
504 VariableArrayType* VT = cast<VariableArrayType>(T);
Ted Kremenek159d2482008-12-09 00:44:16 +0000505 Expr* SizeExpr = VT->getSizeExpr();
Ted Kremenekefd59942008-12-08 22:47:34 +0000506
Ted Kremenek159d2482008-12-09 00:44:16 +0000507 std::string buf;
508 llvm::raw_string_ostream os(buf);
Ted Kremenek5d88ff82009-04-02 02:40:26 +0000509 os << "The expression used to specify the number of elements in the "
510 "variable-length array (VLA) '"
Ted Kremenekcf118d42009-02-04 23:49:09 +0000511 << VD->getNameAsString() << "' evaluates to ";
Ted Kremenek159d2482008-12-09 00:44:16 +0000512
Ted Kremenek23ec48c2009-06-18 23:58:37 +0000513 bool isUndefined = N->getState()->getSVal(SizeExpr).isUndef();
Ted Kremenekd49967f2009-04-29 21:58:13 +0000514
515 if (isUndefined)
Ted Kremenek159d2482008-12-09 00:44:16 +0000516 os << "an undefined or garbage value.";
Ted Kremenekcf118d42009-02-04 23:49:09 +0000517 else
518 os << "0. VLAs with no elements have undefined behavior.";
Ted Kremenekd49967f2009-04-29 21:58:13 +0000519
520 std::string shortBuf;
521 llvm::raw_string_ostream os_short(shortBuf);
522 os_short << "Variable-length array '" << VD->getNameAsString() << "' "
Ted Kremenekeaedfea2009-05-10 05:11:21 +0000523 << (isUndefined ? "garbage value for array size"
524 : "has zero elements (undefined behavior)");
Ted Kremenek159d2482008-12-09 00:44:16 +0000525
Ted Kremenek85ac9342009-05-15 05:25:09 +0000526 ArgReport *report = new ArgReport(*this, os_short.str().c_str(),
527 os.str().c_str(), N, SizeExpr);
528
Ted Kremenekcf118d42009-02-04 23:49:09 +0000529 report->addRange(SizeExpr->getSourceRange());
530 BR.EmitReport(report);
Ted Kremenekefd59942008-12-08 22:47:34 +0000531 }
532 }
Ted Kremenek85ac9342009-05-15 05:25:09 +0000533
534 void registerInitialVisitors(BugReporterContext& BRC,
Zhongxing Xuc5619d92009-08-06 01:32:16 +0000535 const ExplodedNode* N,
Ted Kremenek85ac9342009-05-15 05:25:09 +0000536 BuiltinBugReport *R) {
537 registerTrackNullOrUndefValue(BRC, static_cast<ArgReport*>(R)->getArg(),
538 N);
539 }
Ted Kremenekefd59942008-12-08 22:47:34 +0000540};
Zhongxing Xu1c0c2332008-11-23 05:52:28 +0000541
Ted Kremenek78d46242008-07-22 16:21:24 +0000542//===----------------------------------------------------------------------===//
543// __attribute__(nonnull) checking
544
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000545class VISIBILITY_HIDDEN CheckAttrNonNull :
546 public CheckerVisitor<CheckAttrNonNull> {
547
Ted Kremenekcf118d42009-02-04 23:49:09 +0000548 BugType *BT;
Ted Kremenek78d46242008-07-22 16:21:24 +0000549
550public:
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000551 CheckAttrNonNull() : BT(0) {}
Ted Kremenek31112182009-07-24 00:40:31 +0000552 ~CheckAttrNonNull() {}
Ted Kremenek78d46242008-07-22 16:21:24 +0000553
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000554 const void *getTag() {
555 static int x = 0;
556 return &x;
557 }
558
559 void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE) {
560 const GRState *state = C.getState();
561 const GRState *originalState = state;
Ted Kremenek78d46242008-07-22 16:21:24 +0000562
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000563 // Check if the callee has a 'nonnull' attribute.
Ted Kremenek23ec48c2009-06-18 23:58:37 +0000564 SVal X = state->getSVal(CE->getCallee());
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000565
Zhongxing Xu369f4472009-04-20 05:24:46 +0000566 const FunctionDecl* FD = X.getAsFunctionDecl();
567 if (!FD)
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000568 return;
Zhongxing Xu369f4472009-04-20 05:24:46 +0000569
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000570 const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
Ted Kremenek78d46242008-07-22 16:21:24 +0000571 if (!Att)
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000572 return;
Ted Kremenek78d46242008-07-22 16:21:24 +0000573
574 // Iterate through the arguments of CE and check them for null.
Ted Kremenek78d46242008-07-22 16:21:24 +0000575 unsigned idx = 0;
Ted Kremenek78d46242008-07-22 16:21:24 +0000576
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000577 for (CallExpr::const_arg_iterator I=CE->arg_begin(), E=CE->arg_end(); I!=E;
Ted Kremenek78d46242008-07-22 16:21:24 +0000578 ++I, ++idx) {
Ted Kremenek78d46242008-07-22 16:21:24 +0000579
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000580 if (!Att->isNonNull(idx))
581 continue;
582
Ted Kremenek08780072009-08-24 22:47:34 +0000583 const SVal &V = state->getSVal(*I);
584 const DefinedSVal *DV = dyn_cast<DefinedSVal>(&V);
585
586 if (!DV)
587 continue;
588
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000589 ConstraintManager &CM = C.getConstraintManager();
590 const GRState *stateNotNull, *stateNull;
Ted Kremenek08780072009-08-24 22:47:34 +0000591 llvm::tie(stateNotNull, stateNull) = CM.AssumeDual(state, *DV);
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000592
593 if (stateNull && !stateNotNull) {
594 // Generate an error node. Check for a null node in case
595 // we cache out.
Ted Kremenek592362b2009-08-18 01:05:30 +0000596 if (ExplodedNode *errorNode = C.generateNode(CE, stateNull, true)) {
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000597
598 // Lazily allocate the BugType object if it hasn't already been
599 // created. Ownership is transferred to the BugReporter object once
600 // the BugReport is passed to 'EmitWarning'.
601 if (!BT)
602 BT = new BugType("Argument with 'nonnull' attribute passed null",
603 "API");
604
Ted Kremenek592362b2009-08-18 01:05:30 +0000605 EnhancedBugReport *R =
606 new EnhancedBugReport(*BT,
607 "Null pointer passed as an argument to a "
608 "'nonnull' parameter", errorNode);
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000609
610 // Highlight the range of the argument that was null.
Ted Kremenek592362b2009-08-18 01:05:30 +0000611 const Expr *arg = *I;
612 R->addRange(arg->getSourceRange());
613 R->addVisitorCreator(registerTrackNullOrUndefValue, arg);
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000614
615 // Emit the bug report.
616 C.EmitReport(R);
617 }
618
619 // Always return. Either we cached out or we just emitted an error.
620 return;
621 }
622
623 // If a pointer value passed the check we should assume that it is
624 // indeed not null from this point forward.
625 assert(stateNotNull);
626 state = stateNotNull;
627 }
628
629 // If we reach here all of the arguments passed the nonnull check.
630 // If 'state' has been updated generated a new node.
631 if (state != originalState)
Ted Kremenekbb977222009-07-28 19:24:31 +0000632 C.addTransition(C.generateNode(CE, state));
Ted Kremenek78d46242008-07-22 16:21:24 +0000633 }
Ted Kremenek78d46242008-07-22 16:21:24 +0000634};
635} // end anonymous namespace
636
Zhongxing Xu9a5bca32009-08-29 02:11:01 +0000637// Undefined arguments checking.
638namespace {
639class VISIBILITY_HIDDEN CheckUndefinedArg
640 : public CheckerVisitor<CheckUndefinedArg> {
641
642 BugType *BT;
643
644public:
645 CheckUndefinedArg() : BT(0) {}
646 ~CheckUndefinedArg() {}
647
648 const void *getTag() {
649 static int x = 0;
650 return &x;
651 }
652
653 void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
654};
655
656void CheckUndefinedArg::PreVisitCallExpr(CheckerContext &C, const CallExpr *CE){
657 for (CallExpr::const_arg_iterator I = CE->arg_begin(), E = CE->arg_end();
658 I != E; ++I) {
659 if (C.getState()->getSVal(*I).isUndef()) {
660 if (ExplodedNode *ErrorNode = C.generateNode(CE, C.getState(), true)) {
661 if (!BT)
662 BT = new BugType("Uninitialized argument.", "Logic Errors.");
663 // Generate a report for this bug.
664 ArgReport *Report = new ArgReport(*BT,
665 "Pass-by-value argument in function call is undefined.",
666 ErrorNode, *I);
667 Report->addRange((*I)->getSourceRange());
668 C.EmitReport(Report);
669 }
670 }
671 }
672}
673
674}
Ted Kremenek78d46242008-07-22 16:21:24 +0000675//===----------------------------------------------------------------------===//
676// Check registration.
Ted Kremenekcf118d42009-02-04 23:49:09 +0000677//===----------------------------------------------------------------------===//
Ted Kremenek78d46242008-07-22 16:21:24 +0000678
679void GRExprEngine::RegisterInternalChecks() {
Ted Kremenekcf118d42009-02-04 23:49:09 +0000680 // Register internal "built-in" BugTypes with the BugReporter. These BugTypes
681 // are different than what probably many checks will do since they don't
682 // create BugReports on-the-fly but instead wait until GRExprEngine finishes
683 // analyzing a function. Generation of BugReport objects is done via a call
684 // to 'FlushReports' from BugReporter.
685 BR.Register(new NullDeref(this));
686 BR.Register(new UndefinedDeref(this));
687 BR.Register(new UndefBranch(this));
688 BR.Register(new DivZero(this));
689 BR.Register(new UndefResult(this));
690 BR.Register(new BadCall(this));
691 BR.Register(new RetStack(this));
692 BR.Register(new RetUndef(this));
Ted Kremenekcf118d42009-02-04 23:49:09 +0000693 BR.Register(new BadMsgExprArg(this));
694 BR.Register(new BadReceiver(this));
695 BR.Register(new OutOfBoundMemoryAccess(this));
696 BR.Register(new BadSizeVLA(this));
Ted Kremenek21fe8372009-02-19 04:06:22 +0000697 BR.Register(new NilReceiverStructRet(this));
Ted Kremenek899b3de2009-04-08 03:07:17 +0000698 BR.Register(new NilReceiverLargerThanVoidPtrRet(this));
Ted Kremenekcf118d42009-02-04 23:49:09 +0000699
700 // The following checks do not need to have their associated BugTypes
701 // explicitly registered with the BugReporter. If they issue any BugReports,
702 // their associated BugType will get registered with the BugReporter
703 // automatically. Note that the check itself is owned by the GRExprEngine
704 // object.
Ted Kremenekc26a8b02009-07-22 21:46:56 +0000705 registerCheck(new CheckAttrNonNull());
Zhongxing Xu9a5bca32009-08-29 02:11:01 +0000706 registerCheck(new CheckUndefinedArg());
Ted Kremenek78d46242008-07-22 16:21:24 +0000707}