summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorFilipe Cabecinhas <me@filcab.net>2016-04-29 20:37:34 +0000
committerFilipe Cabecinhas <me@filcab.net>2016-04-29 20:37:34 +0000
commit4a02a8f62de12e8927c21e7c438c201f92a034cf (patch)
tree5699b598db71bb42f8d21280e50179a06e43329b /test
parent4c14c1518b208c5e8b617de6ea22e6c68b96d3f8 (diff)
[asan] Assert in __sanitizer_ptr_{sub,cmp} if one of the pointers was freed.
Summary: This (partially) implements the check mentioned at http://kristerw.blogspot.co.uk/2016/04/dangling-pointers-and-undefined-behavior.html (via John Regehr) Quoting: "That the behavior is undefined follows from C11 6.2.4 "Storage durations of objects" The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime. If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime. and 7.22.3 "Memory management functions" that says that free ends the lifetime of objects The lifetime of an allocated object extends from the allocation until the deallocation. " We can probably implement this for stack variables too, but I think this is a good start to see if there's interest in this check. We can also hide this behind a flag, too. Reviewers: samsonov, kcc, rsmith, regehr Subscribers: kubabrecka, llvm-commits Differential Revision: http://reviews.llvm.org/D19691 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@268097 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs.cc37
1 files changed, 37 insertions, 0 deletions
diff --git a/test/asan/TestCases/invalid-pointer-pairs.cc b/test/asan/TestCases/invalid-pointer-pairs.cc
new file mode 100644
index 000000000..874107cdf
--- /dev/null
+++ b/test/asan/TestCases/invalid-pointer-pairs.cc
@@ -0,0 +1,37 @@
+// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair
+
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 %run %t k 2>&1 | FileCheck %s -check-prefix=OK -allow-empty
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t g 2>&1 | FileCheck %s -check-prefix=CMP -check-prefix=ALL-ERRORS
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t s 2>&1 | FileCheck %s -check-prefix=SUB -check-prefix=ALL-ERRORS
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t f 2>&1 | FileCheck %s -check-prefix=FREE -check-prefix=ALL-ERRORS
+
+#include <assert.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv) {
+ // ALL-ERRORS: ERROR: AddressSanitizer: invalid-pointer-pair
+ // [[PTR1:0x[0-9a-f]+]] [[PTR2:0x[0-9a-f]+]]
+ assert(argc >= 2);
+ char *p = (char *)malloc(42);
+ char *q = (char *)malloc(42);
+ switch (argv[1][0]) {
+ case 'g':
+ // CMP: #0 {{.*}} in main {{.*}}invalid-pointer-pairs.cc:[[@LINE+1]]:14
+ return p > q;
+ case 's':
+ // SUB: #0 {{.*}} in main {{.*}}invalid-pointer-pairs.cc:[[@LINE+1]]:14
+ return p - q;
+ case 'k': {
+ // OK-NOT: ERROR
+ char *p2 = p + 20;
+ return p > p2;
+ }
+ case 'f': {
+ char *p3 = p + 20;
+ free(p);
+ // FREE: #0 {{.*}} in main {{.*}}invalid-pointer-pairs.cc:[[@LINE+2]]:14
+ // FREE: freed by thread
+ return p < p3;
+ }
+ }
+}