> Am 12.04.2024 um 09:50 schrieb Jakub Jelinek <ja...@redhat.com>:
> 
> Hi!
> 
> The tree-cfg.cc verifier only diagnoses returns_twice calls preceded
> by non-label/debug stmts if it is in a bb with abnormal predecessor.
> The following testcase shows that if a user lies in the attributes
> (a function which never returns can't be pure, and can't return
> twice when it doesn't ever return at all), when we figure it out,
> we can remove the abnormal edges to the "returns_twice" call and perhaps
> whole .ABNORMAL_DISPATCHER etc.
> edge_before_returns_twice_call then ICEs because it can't find such
> an edge.
> 
> The following patch limits the special handling to calls in bbs where
> the verifier requires that.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok

Richard 

> 2024-04-12  Jakub Jelinek  <ja...@redhat.com>
> 
>    PR sanitizer/114687
>    * gimple-iterator.cc (gsi_safe_insert_before): Only use
>    edge_before_returns_twice_call if bb_has_abnormal_pred.
>    (gsi_safe_insert_seq_before): Likewise.
>    * gimple-lower-bitint.cc (bitint_large_huge::lower_call): Only
>    push to m_returns_twice_calls if bb_has_abnormal_pred.
> 
>    * gcc.dg/asan/pr114687.c: New test.
> 
> --- gcc/gimple-iterator.cc.jj    2024-03-14 09:57:09.024966285 +0100
> +++ gcc/gimple-iterator.cc    2024-04-11 17:05:06.267081433 +0200
> @@ -1049,7 +1049,8 @@ gsi_safe_insert_before (gimple_stmt_iter
>   gimple *stmt = gsi_stmt (*iter);
>   if (stmt
>       && is_gimple_call (stmt)
> -      && (gimple_call_flags (stmt) & ECF_RETURNS_TWICE) != 0)
> +      && (gimple_call_flags (stmt) & ECF_RETURNS_TWICE) != 0
> +      && bb_has_abnormal_pred (gsi_bb (*iter)))
>     {
>       edge e = edge_before_returns_twice_call (gsi_bb (*iter));
>       basic_block new_bb = gsi_insert_on_edge_immediate (e, g);
> @@ -1072,7 +1073,8 @@ gsi_safe_insert_seq_before (gimple_stmt_
>   gimple *stmt = gsi_stmt (*iter);
>   if (stmt
>       && is_gimple_call (stmt)
> -      && (gimple_call_flags (stmt) & ECF_RETURNS_TWICE) != 0)
> +      && (gimple_call_flags (stmt) & ECF_RETURNS_TWICE) != 0
> +      && bb_has_abnormal_pred (gsi_bb (*iter)))
>     {
>       edge e = edge_before_returns_twice_call (gsi_bb (*iter));
>       gimple *f = gimple_seq_first_stmt (seq);
> --- gcc/gimple-lower-bitint.cc.jj    2024-04-09 09:28:21.261123664 +0200
> +++ gcc/gimple-lower-bitint.cc    2024-04-11 17:06:58.033548199 +0200
> @@ -5320,7 +5320,7 @@ bitint_large_huge::lower_call (tree obj,
>      arg = make_ssa_name (TREE_TYPE (arg));
>      gimple *g = gimple_build_assign (arg, v);
>      gsi_insert_before (&gsi, g, GSI_SAME_STMT);
> -      if (returns_twice)
> +      if (returns_twice && bb_has_abnormal_pred (gimple_bb (stmt)))
>        {
>          m_returns_twice_calls.safe_push (stmt);
>          returns_twice = false;
> --- gcc/testsuite/gcc.dg/asan/pr114687.c.jj    2024-04-11 17:09:54.518127165 
> +0200
> +++ gcc/testsuite/gcc.dg/asan/pr114687.c    2024-04-11 17:09:22.699563654 
> +0200
> @@ -0,0 +1,22 @@
> +/* PR sanitizer/114687 */
> +/* { dg-do compile } */
> +
> +int a;
> +int foo (int);
> +
> +__attribute__((pure, returns_twice)) int
> +bar (void)
> +{
> +  a = 1;
> +  while (a)
> +    a = 2;
> +  return a;
> +}
> +
> +int
> +baz (void)
> +{
> +  int d = bar ();
> +  foo (d);
> +  return 0;
> +}
> 
>    Jakub
> 

Reply via email to