[analyzer] Switched to checkPreCall interface for detecting usage after free.
Now the check is also applied to arguments for Objective-C method calls and to 'this' pointer.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179230 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/NewDelete-checker-test.cpp b/test/Analysis/NewDelete-checker-test.cpp
index bf95221..35125cc 100644
--- a/test/Analysis/NewDelete-checker-test.cpp
+++ b/test/Analysis/NewDelete-checker-test.cpp
@@ -54,7 +54,6 @@
// expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
#endif
-
//----- Standard pointer placement operators
void testGlobalPointerPlacementNew() {
int i;
@@ -91,14 +90,54 @@
// other checks
//---------------
-void f(int *);
+class SomeClass {
+public:
+ void f(int *p);
+};
-void testUseAfterDelete() {
+void f(int *p1, int *p2 = 0, int *p3 = 0);
+void g(SomeClass &c, ...);
+
+void testUseFirstArgAfterDelete() {
int *p = new int;
delete p;
f(p); // expected-warning{{Use of memory after it is freed}}
}
+void testUseMiddleArgAfterDelete(int *p) {
+ delete p;
+ f(0, p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testUseLastArgAfterDelete(int *p) {
+ delete p;
+ f(0, 0, p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testUseRefArgAfterDelete(SomeClass &c) {
+ delete &c;
+ g(c); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testVariadicArgAfterDelete() {
+ SomeClass c;
+ int *p = new int;
+ delete p;
+ g(c, 0, p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testUseMethodArgAfterDelete(int *p) {
+ SomeClass *c = new SomeClass;
+ delete p;
+ c->f(p); // expected-warning{{Use of memory after it is freed}}
+}
+
+void testUseThisAfterDelete() {
+ SomeClass *c = new SomeClass;
+ delete c;
+ c->f(0); // expected-warning{{Use of memory after it is freed}}
+}
+
void testDeleteAlloca() {
int *p = (int *)__builtin_alloca(sizeof(int));
delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}}
diff --git a/test/Analysis/malloc.mm b/test/Analysis/malloc.mm
index bd9d2d2..c7fe86b 100644
--- a/test/Analysis/malloc.mm
+++ b/test/Analysis/malloc.mm
@@ -81,7 +81,17 @@
void *data = malloc(42);
NSData *nsdata;
free(data);
- [NSData dataWithBytesNoCopy:data length:42]; // expected-warning {{Attempt to free released memory}}
+ [NSData dataWithBytesNoCopy:data length:42]; // expected-warning {{Use of memory after it is freed}}
+}
+
+@interface My
++ (void)param:(void *)p;
+@end
+
+void testUseAfterFree() {
+ int *p = (int *)malloc(sizeof(int));
+ free(p);
+ [My param:p]; // expected-warning{{Use of memory after it is freed}}
}
void testNoCopy() {
diff --git a/test/Analysis/new.cpp b/test/Analysis/new.cpp
index 8022430..8d3eee9 100644
--- a/test/Analysis/new.cpp
+++ b/test/Analysis/new.cpp
@@ -8,6 +8,12 @@
extern "C" void free(void *);
int someGlobal;
+
+class SomeClass {
+public:
+ void f(int *p);
+};
+
void testImplicitlyDeclaredGlobalNew() {
if (someGlobal != 0)
return;
@@ -101,6 +107,12 @@
new (&w.x) (int*)(0); // we cache out here; don't crash
}
+void testUseAfter(int *p) {
+ SomeClass *c = new SomeClass;
+ free(p);
+ c->f(p); // expected-warning{{Use of memory after it is freed}}
+ delete c;
+}
//--------------------------------------------------------------------
// Check for intersection with other checkers from MallocChecker.cpp
@@ -152,6 +164,12 @@
p = new(0, p) int; // expected-warning{{Use of memory after it is freed}}
}
+void testUsingThisAfterDelete() {
+ SomeClass *c = new SomeClass;
+ delete c;
+ c->f(0); // no-warning
+}
+
//--------------------------------
// Incorrectly-modelled behavior
//--------------------------------