summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-08-09 00:55:47 +0000
committerJordan Rose <jordan_rose@apple.com>2013-08-09 00:55:47 +0000
commit867b185e63be46d186362774d8c97758c8942aca (patch)
tree6ec0fb37e0993bb3af56603b095435436689d005 /clang/lib/StaticAnalyzer/Checkers
parent368baeda22e48b1f493df9b52ecce064bf323d15 (diff)
downloadbcm5719-llvm-867b185e63be46d186362774d8c97758c8942aca.tar.gz
bcm5719-llvm-867b185e63be46d186362774d8c97758c8942aca.zip
[analyzer] Warn when using 'delete' on an uninitialized variable.
Patch by Karthik Bhat, modified slightly by me. llvm-svn: 188043
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp30
1 files changed, 29 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index c3c5b5e087f..976dcaabf66 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -28,13 +28,16 @@ using namespace ento;
namespace {
class CallAndMessageChecker
- : public Checker< check::PreStmt<CallExpr>, check::PreObjCMessage,
+ : public Checker< check::PreStmt<CallExpr>,
+ check::PreStmt<CXXDeleteExpr>,
+ check::PreObjCMessage,
check::PreCall > {
mutable OwningPtr<BugType> BT_call_null;
mutable OwningPtr<BugType> BT_call_undef;
mutable OwningPtr<BugType> BT_cxx_call_null;
mutable OwningPtr<BugType> BT_cxx_call_undef;
mutable OwningPtr<BugType> BT_call_arg;
+ mutable OwningPtr<BugType> BT_cxx_delete_undef;
mutable OwningPtr<BugType> BT_msg_undef;
mutable OwningPtr<BugType> BT_objc_prop_undef;
mutable OwningPtr<BugType> BT_objc_subscript_undef;
@@ -44,6 +47,7 @@ class CallAndMessageChecker
public:
void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
+ void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
@@ -250,6 +254,30 @@ void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
C.addTransition(StNonNull);
}
+void CallAndMessageChecker::checkPreStmt(const CXXDeleteExpr *DE,
+ CheckerContext &C) const {
+
+ SVal Arg = C.getSVal(DE->getArgument());
+ if (Arg.isUndef()) {
+ StringRef Desc;
+ ExplodedNode *N = C.generateSink();
+ if (!N)
+ return;
+ if (!BT_cxx_delete_undef)
+ BT_cxx_delete_undef.reset(new BuiltinBug("Uninitialized argument value"));
+ if (DE->isArrayFormAsWritten())
+ Desc = "Argument to 'delete[]' is uninitialized";
+ else
+ Desc = "Argument to 'delete' is uninitialized";
+ BugType *BT = BT_cxx_delete_undef.get();
+ BugReport *R = new BugReport(*BT, Desc, N);
+ bugreporter::trackNullOrUndefValue(N, DE, *R);
+ C.emitReport(R);
+ return;
+ }
+}
+
+
void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
OpenPOWER on IntegriCloud