cf94462
2015-02-10  Jakub Jelinek  <jakub@redhat.com>
cf94462
cf94462
	PR sanitizer/65004
cf94462
	* ubsan.c (ubsan_expand_vptr_ifn): Always return true.
cf94462
cf94462
	* g++.dg/asan/pr65004.C: New test.
cf94462
cf94462
--- gcc/ubsan.c.jj	2015-01-28 08:39:53.000000000 +0100
cf94462
+++ gcc/ubsan.c	2015-02-10 18:44:59.796872508 +0100
cf94462
@@ -1148,7 +1148,7 @@ ubsan_expand_vptr_ifn (gimple_stmt_itera
cf94462
   /* Get rid of the UBSAN_VPTR call from the IR.  */
cf94462
   unlink_stmt_vdef (stmt);
cf94462
   gsi_remove (&gsi, true);
cf94462
-  return gsi_end_p (*gsip);
cf94462
+  return true;
cf94462
 }
cf94462
 
cf94462
 /* Instrument a memory reference.  BASE is the base of MEM, IS_LHS says
cf94462
--- gcc/testsuite/g++.dg/asan/pr65004.C.jj	2015-02-10 18:49:48.521988574 +0100
cf94462
+++ gcc/testsuite/g++.dg/asan/pr65004.C	2015-02-10 18:51:22.249407985 +0100
cf94462
@@ -0,0 +1,48 @@
cf94462
+// PR sanitizer/65004
cf94462
+// { dg-do compile }
cf94462
+// { dg-options "-fcompare-debug -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" }
cf94462
+
cf94462
+namespace N {
cf94462
+  template <typename Signature> struct function;
cf94462
+  namespace detail {
cf94462
+    namespace function {
cf94462
+      struct vtable_base { };
cf94462
+    }
cf94462
+  }
cf94462
+  struct function_base {
cf94462
+    detail::function::vtable_base * vtable;
cf94462
+  };
cf94462
+  template <typename R, typename T0> struct function1 : public function_base { };
cf94462
+  template <typename R, typename T0> struct function <R (T0)> : public function1 <R, T0> { };
cf94462
+}
cf94462
+namespace Bar {
cf94462
+  typedef N::function <void (const char *)> WarningHandler;
cf94462
+}
cf94462
+namespace Foo {
cf94462
+  struct FooRecord {
cf94462
+    virtual ~FooRecord ();
cf94462
+  };
cf94462
+  struct TestRecord : public FooRecord {
cf94462
+    long x;
cf94462
+  };
cf94462
+}
cf94462
+namespace Foo {
cf94462
+  using Bar::WarningHandler;
cf94462
+  struct FooScanner {
cf94462
+    WarningHandler warnHandler;
cf94462
+    int readByte ();
cf94462
+    long readSignedInteger ();
cf94462
+  };
cf94462
+  struct FooRecordReader {
cf94462
+    FooScanner & scanner;
cf94462
+    long readSInt ();
cf94462
+    void readTestRecord (TestRecord * recp);
cf94462
+  };
cf94462
+  inline long FooRecordReader::readSInt () {
cf94462
+    return scanner.readSignedInteger ();
cf94462
+  }
cf94462
+  void FooRecordReader::readTestRecord (TestRecord * recp) {
cf94462
+    int infoByte = scanner.readByte ();
cf94462
+    recp->x = readSInt ();
cf94462
+  }
cf94462
+