diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-03-16 08:01:36 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-03-16 08:01:36 +0100 |
commit | 1935f2506e9d4ad4ae4aedb691e5bbd26202ba25 (patch) | |
tree | f013dc14c56a36d06ea0994c23be1cac8f455fea /gcc | |
parent | b2de4950df09c1ec47b1b19eff62745e86663204 (diff) | |
download | gcc-1935f2506e9d4ad4ae4aedb691e5bbd26202ba25.zip gcc-1935f2506e9d4ad4ae4aedb691e5bbd26202ba25.tar.gz gcc-1935f2506e9d4ad4ae4aedb691e5bbd26202ba25.tar.bz2 |
re PR sanitizer/70147 (testcase from hana testsuite gets miscompiled with -fsanitize=undefined)
PR c++/70147
* cp-ubsan.c (cp_ubsan_maybe_initialize_vtbl_ptrs): Temporarily
set in_base_initializer.
* g++.dg/ubsan/pr70147-1.C: New test.
* g++.dg/ubsan/pr70147-2.C: New test.
From-SVN: r234248
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-ubsan.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/pr70147-1.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/pr70147-2.C | 83 |
5 files changed, 113 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4499284..ee2ae89 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-03-16 Jakub Jelinek <jakub@redhat.com> + + PR c++/70147 + * cp-ubsan.c (cp_ubsan_maybe_initialize_vtbl_ptrs): Temporarily + set in_base_initializer. + 2016-03-15 Marek Polacek <polacek@redhat.com> PR c++/70209 diff --git a/gcc/cp/cp-ubsan.c b/gcc/cp/cp-ubsan.c index 2ad0a26..d4759da 100644 --- a/gcc/cp/cp-ubsan.c +++ b/gcc/cp/cp-ubsan.c @@ -318,9 +318,15 @@ cp_ubsan_maybe_initialize_vtbl_ptrs (tree addr) tree type = TREE_TYPE (TREE_TYPE (addr)); tree list = build_tree_list (type, addr); + /* We cannot rely on the vtable being set up. We have to indirect via the + vtt_parm. */ + int save_in_base_initializer = in_base_initializer; + in_base_initializer = 1; /* Walk through the hierarchy, initializing the vptr in each base class to NULL. */ dfs_walk_once (TYPE_BINFO (type), cp_ubsan_dfs_initialize_vtbl_ptrs, NULL, list); + + in_base_initializer = save_in_base_initializer; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2e25991..3f4d614 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-03-16 Jakub Jelinek <jakub@redhat.com> + + PR c++/70147 + * g++.dg/ubsan/pr70147-1.C: New test. + * g++.dg/ubsan/pr70147-2.C: New test. + 2016-03-15 Martin Sebor <msebor@redhat.com> PR c++/58281 diff --git a/gcc/testsuite/g++.dg/ubsan/pr70147-1.C b/gcc/testsuite/g++.dg/ubsan/pr70147-1.C new file mode 100644 index 0000000..f4dd859 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr70147-1.C @@ -0,0 +1,12 @@ +// PR c++/70147 +// { dg-do run } +// { dg-options "-fsanitize=vptr" } + +struct A { A () {} virtual void f () {} }; +struct B : virtual A { B () {} virtual void f () {} }; +struct C : B, virtual A { C () {} } c; + +int +main () +{ +} diff --git a/gcc/testsuite/g++.dg/ubsan/pr70147-2.C b/gcc/testsuite/g++.dg/ubsan/pr70147-2.C new file mode 100644 index 0000000..b74249f --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr70147-2.C @@ -0,0 +1,83 @@ +// PR c++/70147 +// { dg-do run } +// { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } +// { dg-options "-fsanitize=vptr" } + +struct A +{ + A () : a (0) {} + A (int x) : a (x) {} + virtual void f () {} + virtual int i () { int r = 0; __asm ("" : "+r" (r)); return r; } + int a; +}; +struct E +{ + E () : e (0) {} + E (int x) : e (x) {} + virtual void f () {} + virtual int g () { int r = 0; __asm ("" : "+r" (r)); return r; } + int e; +}; +struct F +{ + F () : f (0) {} + F (int x) : f (x) {} + virtual int h () { int r = 0; __asm ("" : "+r" (r)); return r; } + int f; +}; +struct B : virtual A, public E, public F +{ + B () + : E ( + g () + + h () + + i () + ), + F (g () + + h () + + i ()), + b (g () + h () + i ()) // It is ok to call the methods here. + { + b += g () + h () + i (); // And here too. + } + virtual void f () {} + int b; +}; +struct C : B, virtual A +{ + C () {} +}; + +int +main () +{ + C c; +} + +// { dg-output "\[^\n\r]*pr70147-2.C:33:\[0-9]*: runtime error: member call on address 0x\[0-9a-fA-F]* which does not point to an object of type 'E'(\n|\r\n|\r)" } +// { dg-output "0x\[0-9a-fA-F]*: note: object has invalid vptr(\n|\r\n|\r)" } +// { dg-output " ?.. .. .. .. ?.. .. .. .. ?.. .. .. .. \[^\n\r]*(\n|\r\n|\r)" } +// { dg-output " ?\\^~~~~~~~~~~\[^\n\r]*(\n|\r\n|\r)" } +// { dg-output " ?invalid vptr(\n|\r\n|\r)" } +// { dg-output "\[^\n\r]*pr70147-2.C:34:\[0-9]*: runtime error: member call on address 0x\[0-9a-fA-F]* which does not point to an object of type 'F'(\n|\r\n|\r)" } +// { dg-output "0x\[0-9a-fA-F]*: note: object has invalid vptr(\n|\r\n|\r)" } +// { dg-output " ?.. .. .. .. ?.. .. .. .. ?.. .. .. .. \[^\n\r]*(\n|\r\n|\r)" } +// { dg-output " ?\\^~~~~~~~~~~\[^\n\r]*(\n|\r\n|\r)" } +// { dg-output " ?invalid vptr\[^\n\r]*(\n|\r\n|\r)" } +// { dg-output "\[^\n\r]*pr70147-2.C:35:\[0-9]*: runtime error: member call on address 0x\[0-9a-fA-F]* which does not point to an object of type 'A'(\n|\r\n|\r)" } +// { dg-output "0x\[0-9a-fA-F]*: note: object has invalid vptr(\n|\r\n|\r)" } +// { dg-output " ?.. .. .. .. ?.. .. .. .. ?.. .. .. .. \[^\n\r]*(\n|\r\n|\r)" } +// { dg-output " ?\\^~~~~~~~~~~\[^\n\r]*(\n|\r\n|\r)" } +// { dg-output " ?invalid vptr\[^\n\r]*(\n|\r\n|\r)" } +// Note we don't catch the UB of calling g () on line 36. +// { dg-output "\[^\n\r]*pr70147-2.C:38:\[0-9]*: runtime error: member call on address 0x\[0-9a-fA-F]* which does not point to an object of type 'F'(\n|\r\n|\r)" } +// { dg-output "0x\[0-9a-fA-F]*: note: object has invalid vptr(\n|\r\n|\r)" } +// { dg-output " ?.. .. .. .. ?.. .. .. .. ?.. .. .. .. \[^\n\r]*(\n|\r\n|\r)" } +// { dg-output " ?\\^~~~~~~~~~~\[^\n\r]*(\n|\r\n|\r)" } +// { dg-output " ?invalid vptr\[^\n\r]*(\n|\r\n|\r)" } +// { dg-output "\[^\n\r]*pr70147-2.C:39:\[0-9]*: runtime error: member call on address 0x\[0-9a-fA-F]* which does not point to an object of type 'A'(\n|\r\n|\r)" } +// { dg-output "0x\[0-9a-fA-F]*: note: object has invalid vptr(\n|\r\n|\r)" } +// { dg-output " ?.. .. .. .. ?.. .. .. .. ?.. .. .. .. \[^\n\r]*(\n|\r\n|\r)" } +// { dg-output " ?\\^~~~~~~~~~~\[^\n\r]*(\n|\r\n|\r)" } +// { dg-output " ?invalid vptr" } |