r188043 - [analyzer] Warn when using 'delete' on an uninitialized variable.
Jordan Rose
jordan_rose at apple.com
Thu Aug 8 17:55:47 PDT 2013
Author: jrose
Date: Thu Aug 8 19:55:47 2013
New Revision: 188043
URL: http://llvm.org/viewvc/llvm-project?rev=188043&view=rev
Log:
[analyzer] Warn when using 'delete' on an uninitialized variable.
Patch by Karthik Bhat, modified slightly by me.
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
cfe/trunk/test/Analysis/NewDelete-checker-test.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=188043&r1=188042&r2=188043&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp Thu Aug 8 19:55:47 2013
@@ -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
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();
Modified: cfe/trunk/test/Analysis/NewDelete-checker-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NewDelete-checker-test.cpp?rev=188043&r1=188042&r2=188043&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/NewDelete-checker-test.cpp (original)
+++ cfe/trunk/test/Analysis/NewDelete-checker-test.cpp Thu Aug 8 19:55:47 2013
@@ -4,6 +4,7 @@
typedef __typeof__(sizeof(int)) size_t;
extern "C" void *malloc(size_t);
+extern "C" void free (void* ptr);
int *global;
//------------------
@@ -207,6 +208,37 @@ void testConstEscapePlacementNew() {
escapeVoidPtr(y);
} // no-warning
+//============== Test Uninitialized delete delete[]========================
+void testUninitDelete() {
+ int *x;
+ int * y = new int;
+ delete y;
+ delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
+}
+
+void testUninitDeleteArray() {
+ int *x;
+ int * y = new int[5];
+ delete[] y;
+ delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
+}
+
+void testUninitFree() {
+ int *x;
+ free(x); // expected-warning{{Function call argument is an uninitialized value}}
+}
+
+void testUninitDeleteSink() {
+ int *x;
+ delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
+ (*(volatile int *)0 = 1); // no warn
+}
+
+void testUninitDeleteArraySink() {
+ int *x;
+ delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
+ (*(volatile int *)0 = 1); // no warn
+}
namespace reference_count {
class control_block {
More information about the cfe-commits
mailing list