Index: gcc/sanitizer.def
===================================================================
--- gcc/sanitizer.def	(revision 219160)
+++ gcc/sanitizer.def	(working copy)
@@ -167,7 +167,7 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_FUNC_ENTRY, "_
 DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_FUNC_EXIT, "__tsan_func_exit",
 		      BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
 DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VPTR_UPDATE, "__tsan_vptr_update",
-		      BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
+		      BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST)
 DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ1, "__tsan_read1",
 		      BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
 DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ2, "__tsan_read2",
Index: gcc/tsan.c
===================================================================
--- gcc/tsan.c	(revision 219160)
+++ gcc/tsan.c	(working copy)
@@ -241,7 +241,7 @@ instrument_expr (gimple_stmt_iterator gsi, tree ex
   else
     {
       builtin_decl = builtin_decl_implicit (BUILT_IN_TSAN_VPTR_UPDATE);
-      g = gimple_build_call (builtin_decl, 1, expr_ptr);
+      g = gimple_build_call (builtin_decl, 2, expr_ptr, unshare_expr (rhs));
     }
   gimple_set_location (g, loc);
   gimple_seq_add_stmt_without_update (&seq, g);
Index: gcc/testsuite/g++.dg/tsan/vptr_update.C
===================================================================
--- gcc/testsuite/g++.dg/tsan/vptr_update.C	(revision 0)
+++ gcc/testsuite/g++.dg/tsan/vptr_update.C	(working copy)
@@ -0,0 +1,39 @@
+#include <pthread.h>
+
+class thread
+{
+public:
+  thread ()
+  {
+    count = 0;
+    pthread_create (&th, 0, tf, this);
+  }
+
+  virtual ~thread ()
+  {
+    pthread_join (th, 0);
+  }
+
+  virtual void tick ()
+  {
+    count++;
+  }
+
+private:
+  pthread_t th;
+  int count;
+
+  static void* tf(void* arg)
+  {
+    thread* t = (thread*) arg;
+    t->tick();
+    return 0;
+  }
+};
+
+int
+main ()
+{
+  thread *t = new thread;
+  delete t;
+}
