diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-08-01 09:52:43 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-08-01 09:52:43 +0200 |
commit | 944fa280bc92d197c443e369bb24405f007d46ab (patch) | |
tree | 893b88f145db7b629d24315901550a2b349d00ae /gcc/testsuite | |
parent | bbe2542f728dbd46ffc9997537e62228173ffa24 (diff) | |
download | gcc-944fa280bc92d197c443e369bb24405f007d46ab.zip gcc-944fa280bc92d197c443e369bb24405f007d46ab.tar.gz gcc-944fa280bc92d197c443e369bb24405f007d46ab.tar.bz2 |
opts.c (common_handle_option): Handle -fsanitize=alignment.
* opts.c (common_handle_option): Handle -fsanitize=alignment.
* ubsan.h (enum ubsan_null_ckind): Add UBSAN_CTOR_CALL.
(ubsan_expand_bounds_ifn, ubsan_expand_null_ifn): Change return
type to bool.
* stor-layout.h (min_align_of_type): New prototype.
* asan.c (pass_sanopt::execute): Don't perform gsi_next if
ubsan_expand* told us not to do it. Remove the extra gsi_end_p
check.
* ubsan.c: Include builtins.h.
(ubsan_expand_bounds_ifn): Change return type to bool,
always return true.
(ubsan_expand_null_ifn): Change return type to bool, change
argument to gimple_stmt_iterator *. Handle both null and alignment
sanitization, take type from ckind argument's type rather than
first argument.
(instrument_member_call): Removed.
(instrument_mem_ref): Remove t argument, add mem and base arguments.
Handle both null and alignment sanitization, don't say whole
struct access is member access. Build 3 argument IFN_UBSAN_NULL
call instead of 2 argument.
(instrument_null): Adjust instrument_mem_ref caller. Don't
instrument calls here.
(pass_ubsan::gate, pass_ubsan::execute): Handle SANITIZE_ALIGNMENT
like SANITIZE_NULL.
* stor-layout.c (min_align_of_type): New function.
* flag-types.h (enum sanitize_code): Add SANITIZE_ALIGNMENT.
Or it into SANITIZE_UNDEFINED.
* doc/invoke.texi (-fsanitize=alignment): Document.
cp/
* cp-gimplify.c (cp_genericize_r): For -fsanitize=null and/or
-fsanitize=alignment call ubsan_maybe_instrument_reference
for casts to REFERENCE_TYPE and ubsan_maybe_instrument_member_call
for calls to member functions.
c-family/
* c-common.h (min_align_of_type): Removed prototype.
* c-common.c (min_align_of_type): Removed.
* c-ubsan.h (ubsan_maybe_instrument_reference,
ubsan_maybe_instrument_member_call): New prototypes.
* c-ubsan.c: Include stor-layout.h and builtins.h.
(ubsan_maybe_instrument_reference_or_call,
ubsan_maybe_instrument_reference, ubsan_maybe_instrument_call): New
functions.
testsuite/
* c-c++-common/ubsan/align-1.c: New test.
* c-c++-common/ubsan/align-2.c: New test.
* c-c++-common/ubsan/align-3.c: New test.
* c-c++-common/ubsan/align-4.c: New test.
* c-c++-common/ubsan/align-5.c: New test.
* c-c++-common/ubsan/attrib-4.c: New test.
* g++.dg/ubsan/align-1.C: New test.
* g++.dg/ubsan/align-2.C: New test.
* g++.dg/ubsan/align-3.C: New test.
* g++.dg/ubsan/attrib-1.C: New test.
* g++.dg/ubsan/null-1.C: New test.
* g++.dg/ubsan/null-2.C: New test.
From-SVN: r213406
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/ubsan/align-1.c | 41 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/ubsan/align-2.c | 56 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/ubsan/align-3.c | 66 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/ubsan/align-4.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/ubsan/align-5.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/ubsan/attrib-4.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/align-1.C | 27 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/align-2.C | 45 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/align-3.C | 45 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/attrib-1.C | 27 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/null-1.C | 30 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/null-2.C | 39 |
13 files changed, 435 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 37b42b3..cf22371 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2014-08-01 Jakub Jelinek <jakub@redhat.com> + + * c-c++-common/ubsan/align-1.c: New test. + * c-c++-common/ubsan/align-2.c: New test. + * c-c++-common/ubsan/align-3.c: New test. + * c-c++-common/ubsan/align-4.c: New test. + * c-c++-common/ubsan/align-5.c: New test. + * c-c++-common/ubsan/attrib-4.c: New test. + * g++.dg/ubsan/align-1.C: New test. + * g++.dg/ubsan/align-2.C: New test. + * g++.dg/ubsan/align-3.C: New test. + * g++.dg/ubsan/attrib-1.C: New test. + * g++.dg/ubsan/null-1.C: New test. + * g++.dg/ubsan/null-2.C: New test. + 2014-08-01 Tom de Vries <tom@codesourcery.com> * lib/target-supports.exp (check_effective_target_glibc) diff --git a/gcc/testsuite/c-c++-common/ubsan/align-1.c b/gcc/testsuite/c-c++-common/ubsan/align-1.c new file mode 100644 index 0000000..2e40e83 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/align-1.c @@ -0,0 +1,41 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=undefined -fno-sanitize-recover" } */ + +struct S { int a; char b; long long c; short d[10]; }; +struct T { char a; long long b; }; +struct U { char a; int b; int c; long long d; struct S e; struct T f; }; +struct V { long long a; struct S b; struct T c; struct U u; } v; + +__attribute__((noinline, noclone)) void +f1 (int *p, int *q, char *r, long long *s) +{ + *p = *q + *r + *s; +} + + +__attribute__((noinline, noclone)) int +f2 (struct S *p) +{ + return p->a; +} + +__attribute__((noinline, noclone)) long long +f3 (struct S *p, int i) +{ + return p->c + p->d[1] + p->d[i]; +} + +__attribute__((noinline, noclone)) long long +f4 (long long *p) +{ + return *p; +} + +int +main () +{ + f1 (&v.u.b, &v.u.c, &v.u.a, &v.u.d); + if (f2 (&v.u.e) + f3 (&v.u.e, 4) + f4 (&v.u.f.b) != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/ubsan/align-2.c b/gcc/testsuite/c-c++-common/ubsan/align-2.c new file mode 100644 index 0000000..071de8c --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/align-2.c @@ -0,0 +1,56 @@ +/* Limit this to known non-strict alignment targets. */ +/* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */ +/* { dg-options "-fsanitize=alignment" } */ + +struct S { int a; char b; long long c; short d[10]; }; +struct T { char a; long long b; }; +struct U { char a; int b; int c; long long d; struct S e; struct T f; } __attribute__((packed)); +struct V { long long a; struct S b; struct T c; struct U u; } v; + +__attribute__((noinline, noclone)) void +f1 (int *p, int *q, char *r, long long *s) +{ + *p = + *q + + *r + + *s; +} + + +__attribute__((noinline, noclone)) int +f2 (struct S *p) +{ + return p->a; +} + +__attribute__((noinline, noclone)) long long +f3 (struct S *p, int i) +{ + return p->c + + p->d[1] + + p->d[i]; +} + +__attribute__((noinline, noclone)) long long +f4 (long long *p) +{ + return *p; +} + +int +main () +{ + f1 (&v.u.b, &v.u.c, &v.u.a, &v.u.d); + if (f2 (&v.u.e) + f3 (&v.u.e, 4) + f4 (&v.u.f.b) != 0) + __builtin_abort (); + return 0; +} + +/* { dg-output "\.c:(14|15):\[0-9]*: \[^\n\r]*load of misaligned address 0x\[0-9a-fA-F]* for type 'int', which requires 4 byte alignment.*" } */ +/* { dg-output "\.c:16:\[0-9]*: \[^\n\r]*load of misaligned address 0x\[0-9a-fA-F]* for type 'long long int', which requires \[48] byte alignment.*" } */ +/* { dg-output "\.c:(13|16):\[0-9]*: \[^\n\r]*store to misaligned address 0x\[0-9a-fA-F]* for type 'int', which requires 4 byte alignment.*" } */ +/* { dg-output "\.c:23:\[0-9]*: \[^\n\r]*member access within misaligned address 0x\[0-9a-fA-F]* for type 'struct S', which requires \[48] byte alignment.*" } */ +/* { dg-output "\.c:(29|30):\[0-9]*: \[^\n\r]*member access within misaligned address 0x\[0-9a-fA-F]* for type 'struct S', which requires \[48] byte alignment.*" } */ +/* { dg-output "\.c:30:\[0-9]*: \[^\n\r]*member access within misaligned address 0x\[0-9a-fA-F]* for type 'struct S', which requires \[48] byte alignment.*" } */ +/* { dg-output "\.c:31:\[0-9]*: \[^\n\r]*member access within misaligned address 0x\[0-9a-fA-F]* for type 'struct S', which requires \[48] byte alignment.*" } */ +/* { dg-output "\.c:37:\[0-9]*: \[^\n\r]*load of misaligned address 0x\[0-9a-fA-F]* for type 'long long int', which requires \[48] byte alignment" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/align-3.c b/gcc/testsuite/c-c++-common/ubsan/align-3.c new file mode 100644 index 0000000..a509fa9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/align-3.c @@ -0,0 +1,66 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=undefined -fno-sanitize-recover" } */ + +int c; + +__attribute__((noinline, noclone)) void +f1 (int *a, char *b) +{ + __builtin_memcpy (a, b, sizeof (*a)); +} + +__attribute__((noinline, noclone)) void +f2 (int *a, char *b) +{ + __builtin_memcpy (b, a, sizeof (*a)); +} + +__attribute__((noinline, noclone)) void +f3 (char *b) +{ + __builtin_memcpy (&c, b, sizeof (c)); +} + +__attribute__((noinline, noclone)) void +f4 (char *b) +{ + __builtin_memcpy (b, &c, sizeof (c)); +} + +struct T +{ + char a; + short b; + int c; + long d; + long long e; + short f; + float g; + double h; + long double i; +} __attribute__((packed)); + +__attribute__((noinline, noclone)) int +f5 (struct T *p) +{ + return p->a + p->b + p->c + p->d + p->e + p->f + p->g + p->h + p->i; +} + +int +main () +{ + struct S { int a; char b[sizeof (int) + 1]; } s; + s.a = 6; + f2 (&s.a, &s.b[1]); + f1 (&s.a, &s.b[1]); + c = s.a + 1; + f4 (&s.b[1]); + f3 (&s.b[1]); + if (c != 7 || s.a != 6) + __builtin_abort (); + struct U { long long a; long double b; char c; struct T d; } u; + __builtin_memset (&u, 0, sizeof (u)); + if (f5 (&u.d) != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/ubsan/align-4.c b/gcc/testsuite/c-c++-common/ubsan/align-4.c new file mode 100644 index 0000000..3252595 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/align-4.c @@ -0,0 +1,14 @@ +/* Limit this to known non-strict alignment targets. */ +/* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */ +/* { dg-options "-fsanitize=null,alignment" } */ + +#include "align-2.c" + +/* { dg-output "\.c:(14|15):\[0-9]*: \[^\n\r]*load of misaligned address 0x\[0-9a-fA-F]* for type 'int', which requires 4 byte alignment.*" } */ +/* { dg-output "\[^\n\r]*\.c:16:\[0-9]*: \[^\n\r]*load of misaligned address 0x\[0-9a-fA-F]* for type 'long long int', which requires \[48] byte alignment.*" } */ +/* { dg-output "\[^\n\r]*\.c:(13|16):\[0-9]*: \[^\n\r]*store to misaligned address 0x\[0-9a-fA-F]* for type 'int', which requires 4 byte alignment.*" } */ +/* { dg-output "\[^\n\r]*\.c:23:\[0-9]*: \[^\n\r]*member access within misaligned address 0x\[0-9a-fA-F]* for type 'struct S', which requires \[48] byte alignment.*" } */ +/* { dg-output "\[^\n\r]*\.c:(29|30):\[0-9]*: \[^\n\r]*member access within misaligned address 0x\[0-9a-fA-F]* for type 'struct S', which requires \[48] byte alignment.*" } */ +/* { dg-output "\[^\n\r]*\.c:30:\[0-9]*: \[^\n\r]*member access within misaligned address 0x\[0-9a-fA-F]* for type 'struct S', which requires \[48] byte alignment.*" } */ +/* { dg-output "\[^\n\r]*\.c:31:\[0-9]*: \[^\n\r]*member access within misaligned address 0x\[0-9a-fA-F]* for type 'struct S', which requires \[48] byte alignment.*" } */ +/* { dg-output "\[^\n\r]*\.c:37:\[0-9]*: \[^\n\r]*load of misaligned address 0x\[0-9a-fA-F]* for type 'long long int', which requires \[48] byte alignment" } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/align-5.c b/gcc/testsuite/c-c++-common/ubsan/align-5.c new file mode 100644 index 0000000..b94e167 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/align-5.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-fno-sanitize=null -fsanitize=alignment -O2" } */ +/* Check that when optimizing if we know the alignment is right + and we are not doing -fsanitize=null instrumentation we don't + instrument the alignment check. */ + +__attribute__((noinline, noclone)) int +foo (char *p) +{ + p = (char *) __builtin_assume_aligned (p, __alignof__(int)); + int *q = (int *) p; + return *q; +} + +/* { dg-final { scan-assembler-not "__ubsan_handle" } } */ diff --git a/gcc/testsuite/c-c++-common/ubsan/attrib-4.c b/gcc/testsuite/c-c++-common/ubsan/attrib-4.c new file mode 100644 index 0000000..ba0f00c --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/attrib-4.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=undefined" } */ + +/* Test that we don't instrument functions marked with + no_sanitize_undefined attribute. */ + +struct S { int a[16]; }; + +__attribute__((no_sanitize_undefined)) long long +foo (int *a, long long *b, struct S *c) +{ + return a[1] + *b + c->a[a[0]]; +} + +/* { dg-final { scan-assembler-not "__ubsan_handle" } } */ diff --git a/gcc/testsuite/g++.dg/ubsan/align-1.C b/gcc/testsuite/g++.dg/ubsan/align-1.C new file mode 100644 index 0000000..65b1222 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/align-1.C @@ -0,0 +1,27 @@ +// { dg-do run } +// { dg-options "-fsanitize=alignment -Wall -Wno-unused-variable -std=c++11" } + +typedef const long int L; +int a = 1; +L b = 2; + +int +main (void) +{ + int *p = &a; + L *l = &b; + + int &r = *p; + auto &r2 = *p; + L &lr = *l; + + // Try an rvalue reference. + auto &&r3 = *p; + + // Don't evaluate the reference initializer twice. + int i = 1; + int *q = &i; + int &qr = ++*q; + if (i != 2) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/ubsan/align-2.C b/gcc/testsuite/g++.dg/ubsan/align-2.C new file mode 100644 index 0000000..3e4f548 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/align-2.C @@ -0,0 +1,45 @@ +// Limit this to known non-strict alignment targets. +// { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } +// { dg-options "-fsanitize=alignment -Wall -Wno-unused-variable -std=c++11" } + +typedef const long int L; +struct S { long int l; char buf[1 + sizeof (int) + sizeof (L)]; } s; +struct T { char a; int b; long int c; } __attribute__((packed)); +struct U { long int a; struct T b; } u; + +int +main (void) +{ + int *p = (int *) &s.buf[1]; + L *l = (L *) &s.buf[1 + sizeof(int)]; + + int &r = *p; + auto &r2 = *p; + L &lr = *l; + + // Try an rvalue reference. + auto &&r3 = *p; + + // Don't evaluate the reference initializer twice. + int i = 1; + int *q = &i; + int &qr = ++*q; + if (i != 2) + __builtin_abort (); + + int *s = &u.b.b; + L *t = &u.b.c; + int &r4 = *s; + auto &r5 = *s; + L &lr2 = *t; + auto &&r6 = *s; +} + +// { dg-output "\.C:16:\[0-9]*:\[\^\n\r]*reference binding to misaligned address 0x\[0-9a-fA-F]* for type 'int', which requires 4 byte alignment.*" } +// { dg-output "\.C:17:\[0-9]*:\[\^\n\r]*reference binding to misaligned address 0x\[0-9a-fA-F]* for type 'int', which requires 4 byte alignment.*" } +// { dg-output "\.C:18:\[0-9]*:\[\^\n\r]*reference binding to misaligned address 0x\[0-9a-fA-F]* for type 'const L', which requires \[48] byte alignment.*" } +// { dg-output "\.C:21:\[0-9]*:\[\^\n\r]*reference binding to misaligned address 0x\[0-9a-fA-F]* for type 'int', which requires 4 byte alignment.*" } +// { dg-output "\.C:32:\[0-9]*:\[\^\n\r]*reference binding to misaligned address 0x\[0-9a-fA-F]* for type 'int', which requires 4 byte alignment.*" } +// { dg-output "\.C:33:\[0-9]*:\[\^\n\r]*reference binding to misaligned address 0x\[0-9a-fA-F]* for type 'int', which requires 4 byte alignment.*" } +// { dg-output "\.C:34:\[0-9]*:\[\^\n\r]*reference binding to misaligned address 0x\[0-9a-fA-F]* for type 'const L', which requires \[48] byte alignment.*" } +// { dg-output "\.C:35:\[0-9]*:\[\^\n\r]*reference binding to misaligned address 0x\[0-9a-fA-F]* for type 'int', which requires 4 byte alignment" } diff --git a/gcc/testsuite/g++.dg/ubsan/align-3.C b/gcc/testsuite/g++.dg/ubsan/align-3.C new file mode 100644 index 0000000..1cc40fc --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/align-3.C @@ -0,0 +1,45 @@ +// Limit this to known non-strict alignment targets. +// { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } +// { dg-options "-fsanitize=alignment -Wall -Wno-unused-variable -std=c++11" } + +#include <new> + +struct U +{ + int a; + void foo () {} +}; +struct V +{ + V () : a (0) {}; + ~V () { a = 0; }; + int a; + void foo () {} + static void bar () {} +}; +struct S { long int l; char buf[1 + sizeof (U) + 2 * sizeof (V)]; } s; + +int +main (void) +{ + U *p = (U *) &s.buf[1]; + p->foo (); + char *q = &s.buf[1 + sizeof (U)]; + V *u = new (q) V; + u->a = 1; + u->~V (); + V *v = new (&s.buf[1 + sizeof (U) + sizeof (V)]) V; + v->foo (); + v->bar (); // We don't instrument this right now. + v->~V (); +} + +// { dg-output "\.C:26:\[0-9]*:\[\^\n\r]*member call on misaligned address 0x\[0-9a-fA-F]* for type 'struct U', which requires 4 byte alignment.*" } +// { dg-output "\.C:28:\[0-9]*:\[\^\n\r]*constructor call on misaligned address 0x\[0-9a-fA-F]* for type 'struct V', which requires 4 byte alignment.*" } +// { dg-output "\.C:14:\[0-9]*:\[\^\n\r]*member access within misaligned address 0x\[0-9a-fA-F]* for type 'struct V', which requires 4 byte alignment.*" } +// { dg-output "\.C:29:\[0-9]*:\[\^\n\r]*member access within misaligned address 0x\[0-9a-fA-F]* for type 'struct V', which requires 4 byte alignment.*" } +// { dg-output "\.C:30:\[0-9]*:\[\^\n\r]*member call on misaligned address 0x\[0-9a-fA-F]* for type 'struct V', which requires 4 byte alignment.*" } +// { dg-output "\.C:15:\[0-9]*:\[\^\n\r]*member access within misaligned address 0x\[0-9a-fA-F]* for type 'struct V', which requires 4 byte alignment.*" } +// { dg-output "\.C:31:\[0-9]*:\[\^\n\r]*constructor call on misaligned address 0x\[0-9a-fA-F]* for type 'struct V', which requires 4 byte alignment.*" } +// { dg-output "\.C:32:\[0-9]*:\[\^\n\r]*member call on misaligned address 0x\[0-9a-fA-F]* for type 'struct V', which requires 4 byte alignment.*" } +// { dg-output "\.C:34:\[0-9]*:\[\^\n\r]*member call on misaligned address 0x\[0-9a-fA-F]* for type 'struct V', which requires 4 byte alignment" } diff --git a/gcc/testsuite/g++.dg/ubsan/attrib-1.C b/gcc/testsuite/g++.dg/ubsan/attrib-1.C new file mode 100644 index 0000000..f701d02 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/attrib-1.C @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-options "-fsanitize=undefined -Wall -Wno-unused-variable -std=c++11" } + +typedef const long int L; + +__attribute__((no_sanitize_undefined)) void +foo (int *p, L *l) +{ + int &r = *p; + auto &r2 = *p; + L &lr = *l; + auto &&r3 = *p; +} + +struct U +{ + int a; + void foo () {} +}; + +__attribute__((no_sanitize_undefined)) void +bar (U *p) +{ + p->foo (); +} + +// { dg-final { scan-assembler-not "__ubsan_handle" } } diff --git a/gcc/testsuite/g++.dg/ubsan/null-1.C b/gcc/testsuite/g++.dg/ubsan/null-1.C new file mode 100644 index 0000000..e1524b1 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/null-1.C @@ -0,0 +1,30 @@ +// { dg-do run } +// { dg-options "-fsanitize=null -Wall -Wno-unused-variable -std=c++11" } + +typedef const long int L; + +int +main (void) +{ + int *p = 0; + L *l = 0; + + int &r = *p; + auto &r2 = *p; + L &lr = *l; + + // Try an rvalue reference. + auto &&r3 = *p; + + // Don't evaluate the reference initializer twice. + int i = 1; + int *q = &i; + int &qr = ++*q; + if (i != 2) + __builtin_abort (); +} + +// { dg-output "reference binding to null pointer of type 'int'(\n|\r\n|\r)" } +// { dg-output "\[^\n\r]*reference binding to null pointer of type 'int'(\n|\r\n|\r)" } +// { dg-output "\[^\n\r]*reference binding to null pointer of type 'const L'(\n|\r\n|\r)" } +// { dg-output "\[^\n\r]*reference binding to null pointer of type 'int'(\n|\r\n|\r)" } diff --git a/gcc/testsuite/g++.dg/ubsan/null-2.C b/gcc/testsuite/g++.dg/ubsan/null-2.C new file mode 100644 index 0000000..88f387e --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/null-2.C @@ -0,0 +1,39 @@ +// Limit this to known non-strict alignment targets. +// { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } +// { dg-options "-fsanitize=null -Wall -Wno-unused-variable -std=c++11" } + +#include <new> + +struct U +{ + int a; + void foo () {} +}; +struct V +{ + V () {}; + ~V () {}; + int a; + void foo () {} + static void bar () {} +}; +struct S { long int l; char buf[1 + sizeof (U) + 2 * sizeof (V)]; } s; + +int +main (void) +{ + U *p = 0; + p->foo (); + char *q = 0; + V *u = new (q) V; + u->~V (); + V *v = new (q) V; + v->foo (); + v->bar (); // We don't instrument this right now. + v->~V (); +} + +// { dg-output "\.C:26:\[0-9]*:\[\^\n\r]*member call on null pointer of type 'struct U'.*" } +// { dg-output "\.C:29:\[0-9]*:\[\^\n\r]*member call on null pointer of type 'struct V'.*" } +// { dg-output "\.C:31:\[0-9]*:\[\^\n\r]*member call on null pointer of type 'struct V'.*" } +// { dg-output "\.C:33:\[0-9]*:\[\^\n\r]*member call on null pointer of type 'struct V'" } |