On Mon, 20 Mar 2017, Jakub Jelinek wrote:

> Hi!
> 
> libtsan atomics aren't throwing, so if we transform atomics which
> are throwing with -fnon-call-exceptions, we need to clean up EH stuff.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Huh, but this means with TSAN we create wrong-code with 
-fnon-call-exceptions and programs will crash instead of properly
catching things like null-pointer accesses?

We should at least document this or reject sanitize=thread with
-fnon-call-exceptions.

Richard.

> 2017-03-20  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR sanitizer/80110
>       * tsan.c: Include tree-eh.h.
>       (instrument_builtin_call): Call maybe_clean_eh_stmt or
>       maybe_clean_or_replace_eh_stmt where needed.
>       (instrument_memory_accesses): Add cfg_changed argument.
>       Call gimple_purge_dead_eh_edges on each block and set *cfg_changed
>       if it returned true.
>       (tsan_pass): Adjust caller.  Return TODO_cleanup_cfg if cfg_changed.
> 
>       * g++.dg/tsan/pr80110.C: New test.
> 
> --- gcc/tsan.c.jj     2017-03-20 17:55:25.000000000 +0100
> +++ gcc/tsan.c        2017-03-20 19:43:34.715321105 +0100
> @@ -38,6 +38,7 @@ along with GCC; see the file COPYING3.
>  #include "tree-iterator.h"
>  #include "tree-ssa-propagate.h"
>  #include "tree-ssa-loop-ivopts.h"
> +#include "tree-eh.h"
>  #include "tsan.h"
>  #include "asan.h"
>  #include "builtins.h"
> @@ -504,6 +505,7 @@ instrument_builtin_call (gimple_stmt_ite
>             return;
>           gimple_call_set_fndecl (stmt, decl);
>           update_stmt (stmt);
> +         maybe_clean_eh_stmt (stmt);
>           if (tsan_atomic_table[i].action == fetch_op)
>             {
>               args[1] = gimple_call_arg (stmt, 1);
> @@ -524,6 +526,7 @@ instrument_builtin_call (gimple_stmt_ite
>                                      ? MEMMODEL_SEQ_CST
>                                      : MEMMODEL_ACQUIRE);
>           update_gimple_call (gsi, decl, num + 1, args[0], args[1], args[2]);
> +         maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
>           stmt = gsi_stmt (*gsi);
>           if (tsan_atomic_table[i].action == fetch_op_seq_cst)
>             {
> @@ -572,6 +575,7 @@ instrument_builtin_call (gimple_stmt_ite
>             return;
>           update_gimple_call (gsi, decl, 5, args[0], args[1], args[2],
>                               args[4], args[5]);
> +         maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
>           return;
>         case bool_cas:
>         case val_cas:
> @@ -599,6 +603,7 @@ instrument_builtin_call (gimple_stmt_ite
>                                              MEMMODEL_SEQ_CST),
>                               build_int_cst (NULL_TREE,
>                                              MEMMODEL_SEQ_CST));
> +         maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
>           if (tsan_atomic_table[i].action == val_cas && lhs)
>             {
>               tree cond;
> @@ -623,6 +628,7 @@ instrument_builtin_call (gimple_stmt_ite
>                               build_int_cst (t, 0),
>                               build_int_cst (NULL_TREE,
>                                              MEMMODEL_RELEASE));
> +         maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
>           return;
>         case bool_clear:
>         case bool_test_and_set:
> @@ -651,11 +657,13 @@ instrument_builtin_call (gimple_stmt_ite
>             {
>               update_gimple_call (gsi, decl, 3, gimple_call_arg (stmt, 0),
>                                   build_int_cst (t, 0), last_arg);
> +             maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
>               return;
>             }
>           t = build_int_cst (t, targetm.atomic_test_and_set_trueval);
>           update_gimple_call (gsi, decl, 3, gimple_call_arg (stmt, 0),
>                               t, last_arg);
> +         maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (*gsi));
>           stmt = gsi_stmt (*gsi);
>           lhs = gimple_call_lhs (stmt);
>           if (lhs == NULL_TREE)
> @@ -766,7 +774,7 @@ instrument_func_exit (void)
>     Return true if func entry/exit should be instrumented.  */
>  
>  static bool
> -instrument_memory_accesses (void)
> +instrument_memory_accesses (bool *cfg_changed)
>  {
>    basic_block bb;
>    gimple_stmt_iterator gsi;
> @@ -775,20 +783,24 @@ instrument_memory_accesses (void)
>    auto_vec<gimple *> tsan_func_exits;
>  
>    FOR_EACH_BB_FN (bb, cfun)
> -    for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
> -      {
> -     gimple *stmt = gsi_stmt (gsi);
> -     if (gimple_call_internal_p (stmt, IFN_TSAN_FUNC_EXIT))
> -       {
> -         if (fentry_exit_instrument)
> -           replace_func_exit (stmt);
> -         else
> -           tsan_func_exits.safe_push (stmt);
> -         func_exit_seen = true;
> -       }
> -     else
> -       fentry_exit_instrument |= instrument_gimple (&gsi);
> -      }
> +    {
> +      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
> +     {
> +       gimple *stmt = gsi_stmt (gsi);
> +       if (gimple_call_internal_p (stmt, IFN_TSAN_FUNC_EXIT))
> +         {
> +           if (fentry_exit_instrument)
> +             replace_func_exit (stmt);
> +           else
> +             tsan_func_exits.safe_push (stmt);
> +           func_exit_seen = true;
> +         }
> +       else
> +         fentry_exit_instrument |= instrument_gimple (&gsi);
> +     }
> +      if (gimple_purge_dead_eh_edges (bb))
> +     *cfg_changed = true;
> +    }
>    unsigned int i;
>    gimple *stmt;
>    FOR_EACH_VEC_ELT (tsan_func_exits, i, stmt)
> @@ -835,9 +847,10 @@ static unsigned
>  tsan_pass (void)
>  {
>    initialize_sanitizer_builtins ();
> -  if (instrument_memory_accesses ())
> +  bool cfg_changed = false;
> +  if (instrument_memory_accesses (&cfg_changed))
>      instrument_func_entry ();
> -  return 0;
> +  return cfg_changed ? TODO_cleanup_cfg : 0;
>  }
>  
>  /* Inserts __tsan_init () into the list of CTORs.  */
> --- gcc/testsuite/g++.dg/tsan/pr80110.C.jj    2017-03-20 19:51:02.525497662 
> +0100
> +++ gcc/testsuite/g++.dg/tsan/pr80110.C       2017-03-20 19:50:14.000000000 
> +0100
> @@ -0,0 +1,16 @@
> +// PR sanitizer/80110
> +// { dg-do compile }
> +// { dg-options "-fnon-call-exceptions -fsanitize=thread" }
> +
> +struct A
> +{
> +  int b ();
> +  void c () { static int d = b (); }
> +};
> +
> +void
> +foo ()
> +{
> +  A e;
> +  e.c ();
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to