re PR sanitizer/65400 (tsan mis-compiles inlineable C functions)
authorJakub Jelinek <jakub@gcc.gnu.org>
Thu, 19 Mar 2015 10:12:34 +0000 (11:12 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 19 Mar 2015 10:12:34 +0000 (11:12 +0100)
PR sanitizer/65400
* tsan.c (instrument_gimple): Clear tail call flag on
calls.

* c-c++-common/tsan/pr65400-3.c: New test.

From-SVN: r221512

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/tsan/pr65400-3.c [new file with mode: 0644]
gcc/tsan.c

index 251fc3a8ec7953b8f5c3615067bfc6b8204dff20..467b445458b13eaf12eece8f7ebc1d175b4d99d6 100644 (file)
@@ -1,3 +1,10 @@
+2015-03-19  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/65400
+       * tsan.c (instrument_gimple): Clear tail call flag on
+       calls.
+
 2015-03-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR sanitizer/65400
index 378fba23cf2809e3c29eff6b16774dad194db3be..92ad9e1c98cb53f6c8efb93540a9ee72651d83c0 100644 (file)
@@ -1,3 +1,8 @@
+2015-03-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/65400
+       * c-c++-common/tsan/pr65400-3.c: New test.
+
 2015-03-19  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/59686
diff --git a/gcc/testsuite/c-c++-common/tsan/pr65400-3.c b/gcc/testsuite/c-c++-common/tsan/pr65400-3.c
new file mode 100644 (file)
index 0000000..9483bb6
--- /dev/null
@@ -0,0 +1,75 @@
+/* PR sanitizer/65400 */
+/* { dg-shouldfail "tsan" } */
+/* { dg-additional-options "-fno-omit-frame-pointer -ldl" } */
+
+#include <pthread.h>
+#include "tsan_barrier.h"
+
+static pthread_barrier_t barrier;
+int v;
+
+int
+fn1 (int a, int b, int c)
+{
+  int r = (a ^ b) % c;
+  r = r * a * b + c;
+  r = (r ^ b) % c;
+  return r;
+}
+
+int
+fn2 (int a, int b, int c)
+{
+  int r = (a ^ b) % c;
+  r = r * a * b + c;
+  r = (r ^ b) % c;
+  return r;
+}
+
+__attribute__((noinline, noclone)) void
+foo (void)
+{
+  barrier_wait (&barrier);
+  barrier_wait (&barrier);
+  v++;
+}
+
+__attribute__((noinline, noclone)) void
+bar (void)
+{
+  int (*fna) (int, int, int);
+  int (*fnb) (int, int, int);
+  int i;
+  asm ("" : "=g" (fna) : "0" (fn1));
+  asm ("" : "=g" (fnb) : "0" (fn2));
+  for (i = 0; i < 128; i++)
+    {
+      fna (0, 0, i + 1);
+      fnb (0, 0, i + 1);
+    }
+  foo ();
+}
+
+__attribute__((noinline, noclone)) void *
+tf (void *arg)
+{
+  (void) arg;
+  bar ();
+  return NULL;
+}
+
+int
+main ()
+{
+  pthread_t th;
+  barrier_init (&barrier, 2);
+  if (pthread_create (&th, NULL, tf, NULL))
+    return 0;
+  barrier_wait (&barrier);
+  v++;
+  barrier_wait (&barrier);
+  pthread_join (th, NULL);
+  return 0;
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: data race.*#2 _?tf" } */
index ae89d5fdaf618c8f0c288e96689fce5345a1d927..ebafbb03cbdff9fd44aed53c7e68a9835b43d1a8 100644 (file)
@@ -680,6 +680,10 @@ instrument_gimple (gimple_stmt_iterator *gsi)
       && (gimple_call_fndecl (stmt)
          != builtin_decl_implicit (BUILT_IN_TSAN_INIT)))
     {
+      /* All functions with function call will have exit instrumented,
+        therefore no function calls other than __tsan_func_exit
+        shall appear in the functions.  */
+      gimple_call_set_tail (as_a <gcall *> (stmt), false);
       if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
        instrument_builtin_call (gsi);
       return true;