+2015-01-16 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * sanititer.def (BUILT_IN_TSAN_VPTR_UPDATE): Fixed parameters.
+ * tsan.c (instrument_expr): Fixed parameters of __tsan_vptr_update.
+
2015-01-16 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm.md: Move comment about splitting Thumb1 patterns to...
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",
+2015-01-16 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * g++.dg/tsan/vptr_benign_race.C: New testcase.
+ * g++.dg/tsan/vptr_harmful_race.C: New testcase.
+
2015-01-16 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/60056
--- /dev/null
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+
+struct A {
+ A() {
+ sem_init(&sem_, 0, 0);
+ }
+ virtual void F() {
+ }
+ void Done() {
+ sem_post(&sem_);
+ }
+ virtual ~A() {
+ }
+ sem_t sem_;
+};
+
+struct B : A {
+ virtual void F() {
+ }
+ virtual ~B() {
+ sem_wait(&sem_);
+ sem_destroy(&sem_);
+ }
+};
+
+static A *obj = new B;
+
+void *Thread1(void *x) {
+ obj->F();
+ obj->Done();
+ return NULL;
+}
+
+void *Thread2(void *x) {
+ delete obj;
+ return NULL;
+}
+
+int main() {
+ pthread_t t[2];
+ pthread_create(&t[0], NULL, Thread1, NULL);
+ pthread_create(&t[1], NULL, Thread2, NULL);
+ pthread_join(t[0], NULL);
+ pthread_join(t[1], NULL);
+ fprintf(stderr, "PASS\n");
+}
+/* { dg-output "PASS.*" } */
--- /dev/null
+/* { dg-shouldfail "tsan" } */
+/* { dg-additional-options "-ldl" } */
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "tsan_barrier.h"
+
+static pthread_barrier_t barrier;
+
+struct A {
+ A() {
+ sem_init(&sem_, 0, 0);
+ }
+ virtual void F() {
+ }
+ void Done() {
+ sem_post(&sem_);
+ }
+ virtual ~A() {
+ sem_wait(&sem_);
+ sem_destroy(&sem_);
+ }
+ sem_t sem_;
+};
+
+struct B : A {
+ virtual void F() {
+ }
+ virtual ~B() { }
+};
+
+static A *obj = new B;
+
+void *Thread1(void *x) {
+ obj->F();
+ obj->Done();
+ barrier_wait(&barrier);
+ return NULL;
+}
+
+void *Thread2(void *x) {
+ barrier_wait(&barrier);
+ delete obj;
+ return NULL;
+}
+
+int main() {
+ barrier_init(&barrier, 2);
+ pthread_t t[2];
+ pthread_create(&t[0], NULL, Thread1, NULL);
+ pthread_create(&t[1], NULL, Thread2, NULL);
+ pthread_join(t[0], NULL);
+ pthread_join(t[1], NULL);
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: data race on vptr.*(\n|\r\n|\r)" } */
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);