aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-03-16 08:01:36 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2016-03-16 08:01:36 +0100
commit1935f2506e9d4ad4ae4aedb691e5bbd26202ba25 (patch)
treef013dc14c56a36d06ea0994c23be1cac8f455fea
parentb2de4950df09c1ec47b1b19eff62745e86663204 (diff)
downloadgcc-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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-ubsan.c6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr70147-1.C12
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr70147-2.C83
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" }