re PR sanitizer/70147 (testcase from hana testsuite gets miscompiled with -fsanitize...
authorJakub Jelinek <jakub@redhat.com>
Wed, 16 Mar 2016 07:01:36 +0000 (08:01 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 16 Mar 2016 07:01:36 +0000 (08:01 +0100)
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
gcc/cp/cp-ubsan.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ubsan/pr70147-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ubsan/pr70147-2.C [new file with mode: 0644]

index 4499284e65cb196c68ed978edb0774307d272d84..ee2ae896f71d93866d62c16ce695decbc733df17 100644 (file)
@@ -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
index 2ad0a26207f33f42e924b59d33460bdbc1ed781b..d4759da7a25a02d3b604de9ced863c74da9b866f 100644 (file)
@@ -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;
 }
index 2e25991cc4dcfa4f5ab995e7d08e6c6e974d035c..3f4d6142dca014eefa44eec75225fb7ffb576be6 100644 (file)
@@ -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 (file)
index 0000000..f4dd859
--- /dev/null
@@ -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 (file)
index 0000000..b74249f
--- /dev/null
@@ -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" }