Introduce tests for -fsanitize-address-use-after-scope

* 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.

From-SVN: r241897
This commit is contained in:
Martin Liska 2016-11-07 11:25:18 +01:00 committed by Martin Liska
parent 6dc4a60450
commit 00d6b7a1a7
26 changed files with 589 additions and 1 deletions

View File

@ -1,3 +1,33 @@
2016-11-07 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.
2016-11-07 Richard Biener <rguenther@suse.de>
PR tree-optimization/78189

View File

@ -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))

View File

@ -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" } } */

View File

@ -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.*" }

View File

@ -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.*" }

View File

@ -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.*" }

View File

@ -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.*" }

View File

@ -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.*" }

View File

@ -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.*" }

View File

@ -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.*" }

View File

@ -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.*" }

View File

@ -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();
}

View File

@ -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.*" }

View File

@ -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.*" }

View File

@ -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.*" }

View File

@ -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';
}

View File

@ -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.*" }

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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" } } */

View File

@ -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.*" }

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */