From 1935f2506e9d4ad4ae4aedb691e5bbd26202ba25 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 16 Mar 2016 08:01:36 +0100 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 6 ++ gcc/cp/cp-ubsan.c | 6 ++ gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/g++.dg/ubsan/pr70147-1.C | 12 ++++ gcc/testsuite/g++.dg/ubsan/pr70147-2.C | 83 ++++++++++++++++++++++++++ 5 files changed, 113 insertions(+) create mode 100644 gcc/testsuite/g++.dg/ubsan/pr70147-1.C create mode 100644 gcc/testsuite/g++.dg/ubsan/pr70147-2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4499284e65c..ee2ae896f71 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-03-16 Jakub Jelinek + + PR c++/70147 + * cp-ubsan.c (cp_ubsan_maybe_initialize_vtbl_ptrs): Temporarily + set in_base_initializer. + 2016-03-15 Marek Polacek PR c++/70209 diff --git a/gcc/cp/cp-ubsan.c b/gcc/cp/cp-ubsan.c index 2ad0a26207f..d4759da7a25 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 2e25991cc4d..3f4d6142dca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-03-16 Jakub Jelinek + + PR c++/70147 + * g++.dg/ubsan/pr70147-1.C: New test. + * g++.dg/ubsan/pr70147-2.C: New test. + 2016-03-15 Martin Sebor 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 00000000000..f4dd859450d --- /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 00000000000..b74249fe3ec --- /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" } -- 2.30.2