blob: 4175e8d141057f382117119b7bfa3fa4e97ff587 [file] [log] [blame]
Zhongxing Xu4f64e5f2009-11-03 05:48:04 +00001//===--- BadCallChecker.h - Bad call 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 BadCallChecker, a builtin check in GRExprEngine that performs
11// checks for bad callee at call sites.
12//
13//===----------------------------------------------------------------------===//
14
Ted Kremenekf493f492009-11-11 05:50:44 +000015#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
Zhongxing Xu4f64e5f2009-11-03 05:48:04 +000016#include "clang/Analysis/PathSensitive/BugReporter.h"
Ted Kremenekf493f492009-11-11 05:50:44 +000017#include "GRExprEngineInternalChecks.h"
Zhongxing Xu4f64e5f2009-11-03 05:48:04 +000018
19using namespace clang;
20
Ted Kremenekf493f492009-11-11 05:50:44 +000021namespace {
22class VISIBILITY_HIDDEN BadCallChecker : public CheckerVisitor<BadCallChecker> {
23 BuiltinBug *BT;
24public:
25 BadCallChecker() : BT(0) {}
26 static void *getTag() {
27 static int x = 0;
28 return &x;
29 }
30 void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
31};
32} // end anonymous namespace
33
34void clang::RegisterBadCallChecker(GRExprEngine &Eng) {
35 Eng.registerCheck(new BadCallChecker());
Zhongxing Xu4f64e5f2009-11-03 05:48:04 +000036}
37
38void BadCallChecker::PreVisitCallExpr(CheckerContext &C, const CallExpr *CE) {
39 const Expr *Callee = CE->getCallee()->IgnoreParens();
40 SVal L = C.getState()->getSVal(Callee);
41
42 if (L.isUndef() || isa<loc::ConcreteInt>(L)) {
43 if (ExplodedNode *N = C.GenerateNode(CE, true)) {
44 if (!BT)
Ted Kremenekf493f492009-11-11 05:50:44 +000045 BT = new BuiltinBug("Invalid function call",
Zhongxing Xu4f64e5f2009-11-03 05:48:04 +000046 "Called function pointer is a null or undefined pointer value");
47
48 EnhancedBugReport *R =
49 new EnhancedBugReport(*BT, BT->getDescription().c_str(), N);
50
51 R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
52 bugreporter::GetCalleeExpr(N));
53
54 C.EmitReport(R);
55 }
56 }
57}