aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2015-03-19 11:12:34 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2015-03-19 11:12:34 +0100
commita3f94967e1dc590516bd10938bb049af8441f1a3 (patch)
tree0dea73fba72b7c5ab55b5fcbd0390f21580d0ee3
parent9308995b0acf2f8bbfdbc63d3f950494388f6fa8 (diff)
downloadgcc-a3f94967e1dc590516bd10938bb049af8441f1a3.zip
gcc-a3f94967e1dc590516bd10938bb049af8441f1a3.tar.gz
gcc-a3f94967e1dc590516bd10938bb049af8441f1a3.tar.bz2
re PR sanitizer/65400 (tsan mis-compiles inlineable C functions)
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/tsan/pr65400-3.c75
-rw-r--r--gcc/tsan.c4
4 files changed, 91 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 251fc3a..467b445 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 378fba2..92ad9e1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..9483bb6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/pr65400-3.c
@@ -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" } */
diff --git a/gcc/tsan.c b/gcc/tsan.c
index ae89d5f..ebafbb0 100644
--- a/gcc/tsan.c
+++ b/gcc/tsan.c
@@ -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;