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
This commit is contained in:
Jakub Jelinek 2015-03-19 11:12:34 +01:00
parent 9308995b0a
commit a3f94967e1
4 changed files with 91 additions and 0 deletions

View 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

View 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

View File

@ -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" } */

View 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;