Message ID | Zhjnqav/TqHFN39y@tucnak |
---|---|
State | New |
Headers | show |
Series | Limit special asan/ubsan/bitint returns_twice handling to calls in bbs with abnormal pred [PR114687] | expand |
> Am 12.04.2024 um 09:50 schrieb Jakub Jelinek <jakub@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 <jakub@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 >
--- 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; +}