From e790d926afd3d2d6ad41d14d1e91698bf651b41a Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Mon, 19 Sep 2016 17:39:29 +0200
Subject: [PATCH 2/2] Introduce tests for -fsanitize-address-use-after-scope
gcc/testsuite/ChangeLog:
2016-09-26 Martin Liska <mliska@suse.cz>
* c-c++-common/asan/force-inline-opt0-1.c: Disable
-f-sanitize-address-use-after-scope.
* c-c++-common/asan/inc.c: Change number of expected ASAN_CHECK
internal fn calls.
* g++.dg/asan/use-after-scope-1.C: New test.
* g++.dg/asan/use-after-scope-2.C: Likewise.
* g++.dg/asan/use-after-scope-3.C: Likewise.
* g++.dg/asan/use-after-scope-types-1.C: Likewise.
* g++.dg/asan/use-after-scope-types-2.C: Likewise.
* g++.dg/asan/use-after-scope-types-3.C: Likewise.
* g++.dg/asan/use-after-scope-types-4.C: Likewise.
* g++.dg/asan/use-after-scope-types-5.C: Likewise.
* g++.dg/asan/use-after-scope-types.h: Likewise.
* gcc.dg/asan/use-after-scope-1.c: Likewise.
* gcc.dg/asan/use-after-scope-2.c: Likewise.
* gcc.dg/asan/use-after-scope-3.c: Likewise.
* gcc.dg/asan/use-after-scope-4.c: Likewise.
* gcc.dg/asan/use-after-scope-5.c: Likewise.
* gcc.dg/asan/use-after-scope-6.c: Likewise.
* gcc.dg/asan/use-after-scope-7.c: Likewise.
* gcc.dg/asan/use-after-scope-8.c: Likewise.
* gcc.dg/asan/use-after-scope-9.c: Likewise.
* gcc.dg/asan/use-after-scope-switch-1.c: Likewise.
* gcc.dg/asan/use-after-scope-switch-2.c: Likewise.
* gcc.dg/asan/use-after-scope-switch-3.c: Likewise.
* gcc.dg/asan/use-after-scope-goto-1.c: Likewise.
* gcc.dg/asan/use-after-scope-goto-2.c: Likewise.
---
.../c-c++-common/asan/force-inline-opt0-1.c | 1 +
gcc/testsuite/c-c++-common/asan/inc.c | 3 +-
gcc/testsuite/g++.dg/asan/use-after-scope-1.C | 21 ++++++++++
gcc/testsuite/g++.dg/asan/use-after-scope-2.C | 40 ++++++++++++++++++
gcc/testsuite/g++.dg/asan/use-after-scope-3.C | 22 ++++++++++
.../g++.dg/asan/use-after-scope-types-1.C | 17 ++++++++
.../g++.dg/asan/use-after-scope-types-2.C | 17 ++++++++
.../g++.dg/asan/use-after-scope-types-3.C | 17 ++++++++
.../g++.dg/asan/use-after-scope-types-4.C | 17 ++++++++
.../g++.dg/asan/use-after-scope-types-5.C | 17 ++++++++
gcc/testsuite/g++.dg/asan/use-after-scope-types.h | 30 ++++++++++++++
gcc/testsuite/gcc.dg/asan/use-after-scope-1.c | 18 +++++++++
gcc/testsuite/gcc.dg/asan/use-after-scope-2.c | 47 ++++++++++++++++++++++
gcc/testsuite/gcc.dg/asan/use-after-scope-3.c | 20 +++++++++
gcc/testsuite/gcc.dg/asan/use-after-scope-4.c | 16 ++++++++
gcc/testsuite/gcc.dg/asan/use-after-scope-5.c | 27 +++++++++++++
gcc/testsuite/gcc.dg/asan/use-after-scope-6.c | 15 +++++++
gcc/testsuite/gcc.dg/asan/use-after-scope-7.c | 15 +++++++
gcc/testsuite/gcc.dg/asan/use-after-scope-8.c | 14 +++++++
gcc/testsuite/gcc.dg/asan/use-after-scope-9.c | 20 +++++++++
gcc/testsuite/gcc.dg/asan/use-after-scope-goto-1.c | 47 ++++++++++++++++++++++
gcc/testsuite/gcc.dg/asan/use-after-scope-goto-2.c | 25 ++++++++++++
.../gcc.dg/asan/use-after-scope-switch-1.c | 25 ++++++++++++
.../gcc.dg/asan/use-after-scope-switch-2.c | 33 +++++++++++++++
.../gcc.dg/asan/use-after-scope-switch-3.c | 36 +++++++++++++++++
25 files changed, 559 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/asan/use-after-scope-1.C
create mode 100644 gcc/testsuite/g++.dg/asan/use-after-scope-2.C
create mode 100644 gcc/testsuite/g++.dg/asan/use-after-scope-3.C
create mode 100644 gcc/testsuite/g++.dg/asan/use-after-scope-types-1.C
create mode 100644 gcc/testsuite/g++.dg/asan/use-after-scope-types-2.C
create mode 100644 gcc/testsuite/g++.dg/asan/use-after-scope-types-3.C
create mode 100644 gcc/testsuite/g++.dg/asan/use-after-scope-types-4.C
create mode 100644 gcc/testsuite/g++.dg/asan/use-after-scope-types-5.C
create mode 100644 gcc/testsuite/g++.dg/asan/use-after-scope-types.h
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-1.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-2.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-3.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-4.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-5.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-6.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-7.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-8.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-9.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-goto-1.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-goto-2.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-switch-1.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-switch-2.c
create mode 100644 gcc/testsuite/gcc.dg/asan/use-after-scope-switch-3.c
@@ -2,6 +2,7 @@
(before and after inlining) */
/* { dg-do compile } */
+/* { dg-options "-fno-sanitize-address-use-after-scope" } */
/* { dg-final { scan-assembler-not "__asan_report_load" } } */
__attribute__((always_inline))
@@ -16,5 +16,6 @@ main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "ASAN_" 1 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "ASAN_" 4 "asan0" } } */
/* { dg-final { scan-tree-dump "ASAN_CHECK \\(.*, 4\\);" "asan0" } } */
+/* { dg-final { scan-tree-dump "ASAN_CHECK \\(.*, 8\\);" "asan0" } } */
new file mode 100644
@@ -0,0 +1,21 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+#include <functional>
+
+int main() {
+ std::function<int()> function;
+ {
+ int v = 0;
+ function = [&v]()
+ {
+ return v;
+ };
+ }
+ return function();
+}
+
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "READ of size 4 at.*" }
+// { dg-output ".*'v' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,40 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+#include <stdio.h>
+
+struct Test
+{
+ Test ()
+ {
+ my_value = 0;
+ }
+
+ ~Test ()
+ {
+ fprintf (stderr, "Value: %d\n", *my_value);
+ }
+
+ void init (int *v)
+ {
+ my_value = v;
+ }
+
+ int *my_value;
+};
+
+int main(int argc, char **argv)
+{
+ Test t;
+
+ {
+ int x = argc;
+ t.init(&x);
+ }
+
+ return 0;
+}
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "READ of size 4 at.*" }
+// { dg-output ".*'x' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,22 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+struct IntHolder {
+ int val;
+};
+
+const IntHolder *saved;
+
+void save(const IntHolder &holder) {
+ saved = &holder;
+}
+
+int main(int argc, char *argv[]) {
+ save({10});
+ int x = saved->val; // BOOM
+ return x;
+}
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "READ of size 4 at.*" }
+// { dg-output ".*'<unknown>' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,17 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+#include "use-after-scope-types.h"
+
+int main()
+{
+ using Tests = void (*)();
+ Tests t = &test<bool>;
+ t();
+
+ return 0;
+}
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "WRITE of size " }
+// { dg-output ".*'x' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,17 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+#include "use-after-scope-types.h"
+
+int main()
+{
+ using Tests = void (*)();
+ Tests t = &test<float>;
+ t();
+
+ return 0;
+}
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "WRITE of size " }
+// { dg-output ".*'x' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,17 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+#include "use-after-scope-types.h"
+
+int main()
+{
+ using Tests = void (*)();
+ Tests t = &test<void *>;
+ t();
+
+ return 0;
+}
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "WRITE of size " }
+// { dg-output ".*'x' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,17 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+#include "use-after-scope-types.h"
+
+int main()
+{
+ using Tests = void (*)();
+ Tests t = &test<std::vector<std::string>>;
+ t();
+
+ return 0;
+}
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "READ of size 8 at" }
+// { dg-output ".*'x' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,17 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+#include "use-after-scope-types.h"
+
+int main()
+{
+ using Tests = void (*)();
+ Tests t = &test<char[1000]>;
+ t();
+
+ return 0;
+}
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "WRITE of size " }
+// { dg-output ".*'x' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,30 @@
+#include <stdlib.h>
+#include <string>
+#include <vector>
+
+template <class T> struct Ptr {
+ void Store(T *ptr) { t = ptr; }
+
+ void Access() { *t = {}; }
+
+ T *t;
+};
+
+template <class T, size_t N> struct Ptr<T[N]> {
+ using Type = T[N];
+ void Store(Type *ptr) { t = *ptr; }
+
+ void Access() { *t = {}; }
+
+ T *t;
+};
+
+template <class T> __attribute__((noinline)) void test() {
+ Ptr<T> ptr;
+ {
+ T x;
+ ptr.Store(&x);
+ }
+
+ ptr.Access();
+}
new file mode 100644
@@ -0,0 +1,18 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+int
+main (void)
+{
+ char *ptr;
+ {
+ char my_char[9];
+ ptr = &my_char[0];
+ }
+
+ return *(ptr+8);
+}
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "READ of size 1 at.*" }
+// { dg-output ".*'my_char' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,47 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+int *bar (int *x, int *y) { return y; }
+
+int foo (void)
+{
+ char *p;
+ {
+ char a = 0;
+ p = &a;
+ }
+
+ if (*p)
+ return 1;
+ else
+ return 0;
+}
+
+int
+main (void)
+{
+ char *ptr;
+ {
+ char my_char[9];
+ ptr = &my_char[0];
+ }
+
+ int a[16];
+ int *p, *q = a;
+ {
+ int b[16];
+ p = bar (a, b);
+ }
+ bar (a, q);
+ {
+ int c[16];
+ q = bar (a, c);
+ }
+ int v = *bar (a, q);
+ return v;
+}
+
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "READ of size 4 at.*" }
+// { dg-output ".*'c' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,20 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+int
+main (void)
+{
+ char *ptr;
+ char *ptr2;
+ {
+ char my_char[9];
+ ptr = &my_char[0];
+ __builtin_memcpy (&ptr2, &ptr, sizeof (ptr2));
+ }
+
+ *(ptr2+9) = 'c';
+}
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "WRITE of size 1 at.*" }
+// { dg-output ".*'my_char' <== Memory access at offset \[0-9\]* overflows this variable.*" }
new file mode 100644
@@ -0,0 +1,16 @@
+// { dg-do run }
+
+int
+__attribute__((no_sanitize_address))
+main (void)
+{
+ char *ptr;
+ char *ptr2;
+ {
+ char my_char[9];
+ ptr = &my_char[0];
+ __builtin_memcpy (&ptr2, &ptr, sizeof (ptr2));
+ }
+
+ *(ptr2+9) = 'c';
+}
new file mode 100644
@@ -0,0 +1,27 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+int *ptr;
+
+__attribute__((always_inline))
+inline static void
+foo(int v)
+{
+ int values[10];
+ for (unsigned i = 0; i < 10; i++)
+ values[i] = v;
+
+ ptr = &values[3];
+}
+
+int
+main (int argc, char **argv)
+{
+ foo (argc);
+
+ return *ptr;
+}
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "READ of size 4 at.*" }
+// { dg-output ".*'values' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,15 @@
+// { dg-do run }
+// { dg-additional-options "--param asan-stack=0" }
+
+int
+main (void)
+{
+ char *ptr;
+ {
+ char my_char[9];
+ ptr = &my_char[0];
+ }
+
+ *ptr = 'c';
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,15 @@
+// { dg-do run }
+// { dg-additional-options "-fno-sanitize-address-use-after-scope" }
+
+int
+main (void)
+{
+ char *ptr;
+ {
+ char my_char[9];
+ ptr = &my_char[0];
+ }
+
+ *ptr = 'c';
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,14 @@
+// { dg-do compile }
+// { dg-additional-options "-fdump-tree-asan0" }
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+
+int
+fn1 ()
+{
+ int x = 123;
+ register int a asm("rdi") = 123;
+
+ return x * x;
+}
+
+/* { dg-final { scan-tree-dump-not "ASAN_CHECK" "asan0" } } */
new file mode 100644
@@ -0,0 +1,20 @@
+// { dg-do run }
+// { dg-shouldfail "asan" }
+
+int
+main (int argc, char **argv)
+{
+ int *ptr = 0;
+
+ {
+ int a;
+ ptr = &a;
+ *ptr = 12345;
+ }
+
+ return *ptr;
+}
+
+// { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
+// { dg-output "READ of size .*" }
+// { dg-output ".*'a' <== Memory access at offset \[0-9\]* is inside this variable.*" }
new file mode 100644
@@ -0,0 +1,47 @@
+// { dg-do run }
+// { dg-additional-options "-fdump-tree-asan0" }
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+
+int main(int argc, char **argv)
+{
+ int a = 123;
+ int b = 123;
+ int c = 123;
+ int d = 123;
+ int e = 123;
+ int f = 123;
+
+ if (argc == 0)
+ {
+ int *ptr;
+ int *ptr2;
+ int *ptr3;
+ int *ptr4;
+ int *ptr5;
+ int *ptr6;
+ label:
+ {
+ ptr = &a;
+ *ptr = 1;
+ ptr2 = &b;
+ *ptr2 = 1;
+ ptr3 = &c;
+ *ptr3 = 1;
+ ptr4 = &d;
+ *ptr4 = 1;
+ ptr5 = &e;
+ *ptr5 = 1;
+ ptr6 = &f;
+ *ptr6 = 1;
+ return 0;
+ }
+ }
+ else
+ goto label;
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(2, &a, 4\\);" 2 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(2, &c, 4\\);" 2 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(2, &e, 4\\);" 2 "asan0" } } */
new file mode 100644
@@ -0,0 +1,25 @@
+// { dg-do run }
+// { dg-additional-options "-fdump-tree-asan0" }
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+
+int main(int argc, char **argv)
+{
+ int a = 123;
+
+ if (argc == 0)
+ {
+ int *ptr;
+ /* The label is not used in &label or goto label. Thus '&a' should be
+ marked just once. */
+ label:
+ {
+ ptr = &a;
+ *ptr = 1;
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(2, &a, 4\\);" 1 "asan0" } } */
new file mode 100644
@@ -0,0 +1,25 @@
+// { dg-do run }
+// { dg-additional-options "-fdump-tree-gimple" }
+
+int
+main (int argc, char **argv)
+{
+ int *ptr = 0;
+
+ for (unsigned i = 0; i < 2; i++)
+ {
+ switch (argc)
+ {
+ int a;
+ default:
+ ptr = &a;
+ *ptr = 12345;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(2, &a, \[0-9\]\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(1, &a, \[0-9\]\\);" 1 "gimple" } } */
new file mode 100644
@@ -0,0 +1,33 @@
+// { dg-do run }
+// { dg-additional-options "-fdump-tree-gimple" }
+
+int
+main (int argc, char **argv)
+{
+ int *ptr = 0;
+ int *ptr2 = 0;
+ int *ptr3 = 0;
+
+ for (unsigned i = 0; i < 2; i++)
+ {
+ switch (argc)
+ {
+ case 1111:;
+ int a, b, c;
+ default:
+ ptr = &a;
+ ptr2 = &b;
+ ptr3 = &c;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(2, &a, \[0-9\]\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(2, &b, \[0-9\]\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(2, &c, \[0-9\]\\);" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(1, &a, \[0-9\]\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(1, &b, \[0-9\]\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(1, &c, \[0-9\]\\);" 1 "gimple" } } */
new file mode 100644
@@ -0,0 +1,36 @@
+// { dg-do run }
+// { dg-additional-options "-fdump-tree-gimple" }
+
+int
+main (int argc, char **argv)
+{
+ int *ptr = 0;
+
+ for (unsigned i = 0; i < 2; i++)
+ {
+ switch (argc)
+ {
+ case 11111:;
+ int a;
+ ptr = &a;
+ break;
+ {
+ default:
+ ptr = &a;
+ *ptr = 12345;
+ case 222222:
+ my_label:
+ ptr = &a;
+ break;
+ }
+ }
+ }
+
+ if (argc == 333333)
+ goto my_label;
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(2, &a, \[0-9\]\\);" 4 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "ASAN_MARK \\(1, &a, \[0-9\]\\);" 1 "gimple" } } */
--
2.10.1