diff options
| author | Jordan Rose <jordan_rose@apple.com> | 2013-08-09 00:55:47 +0000 |
|---|---|---|
| committer | Jordan Rose <jordan_rose@apple.com> | 2013-08-09 00:55:47 +0000 |
| commit | 867b185e63be46d186362774d8c97758c8942aca (patch) | |
| tree | 6ec0fb37e0993bb3af56603b095435436689d005 /clang/lib/StaticAnalyzer/Checkers | |
| parent | 368baeda22e48b1f493df9b52ecce064bf323d15 (diff) | |
| download | bcm5719-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.cpp | 30 |
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(); |

