aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2022-09-07 12:01:34 +0200
committerRichard Biener <rguenther@suse.de>2022-09-08 16:05:17 +0200
commit78ef801b7263606d27a6a752a40cbeecc584fb3d (patch)
treeb523e083051e0bed3f186cc7716ece05e98c280f /gcc
parent4db3cb781c355341fa041e6b5bbbfc495c6a0fdb (diff)
downloadgcc-78ef801b7263606d27a6a752a40cbeecc584fb3d.zip
gcc-78ef801b7263606d27a6a752a40cbeecc584fb3d.tar.gz
gcc-78ef801b7263606d27a6a752a40cbeecc584fb3d.tar.bz2
Fix some gimple_ctrl_altering_p mistakes
CFG cleanup resets the control altering flag for noreturn functions when they are ECF_LEAF (like __builtin_unreachable ()). The .ABNORMAL_DISPATCHER call built during CFG construction is not marked as control altering. Several passes inserting traps or unreachables fail to set the flag. And more. PR middle-end/106870 * gimple-harden-conditionals.cc (insert_check_and_trap): Set the control-altering flag on the built IFN_TRAP. * gimple.cc (gimple_build_builtin_unreachable): Likewise. * tree-cfg.cc (handle_abnormal_edges): Set the control-altering flag on the .ABNORMAL_DISPATCHER call. * tree-cfgcleanup.cc (cleanup_call_ctrl_altering_flag): Avoid resetting the control altering flag for ECF_NORETURN calls. (cleanup_control_flow_bb): Set the control altering flag on discovered noreturn calls. * symtab-thunks.cc (expand_thunk): Set the control altering flag for the noreturn tailcall case. * tree-eh.cc (lower_resx): Likewisw for trap and unwind_resume calls.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimple-harden-conditionals.cc1
-rw-r--r--gcc/gimple.cc1
-rw-r--r--gcc/symtab-thunks.cc1
-rw-r--r--gcc/tree-cfg.cc3
-rw-r--r--gcc/tree-cfgcleanup.cc11
-rw-r--r--gcc/tree-eh.cc4
6 files changed, 16 insertions, 5 deletions
diff --git a/gcc/gimple-harden-conditionals.cc b/gcc/gimple-harden-conditionals.cc
index 4ca6776..1b3dd56 100644
--- a/gcc/gimple-harden-conditionals.cc
+++ b/gcc/gimple-harden-conditionals.cc
@@ -238,6 +238,7 @@ insert_check_and_trap (location_t loc, gimple_stmt_iterator *gsip,
gimple_stmt_iterator gsit = gsi_after_labels (trp);
gcall *trap = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
+ gimple_call_set_ctrl_altering (trap, true);
gimple_set_location (trap, loc);
gsi_insert_before (&gsit, trap, GSI_SAME_STMT);
diff --git a/gcc/gimple.cc b/gcc/gimple.cc
index cd5ad0c..4d45311 100644
--- a/gcc/gimple.cc
+++ b/gcc/gimple.cc
@@ -440,6 +440,7 @@ gimple_build_builtin_unreachable (location_t loc)
gcc_checking_assert (data == NULL_TREE);
g = gimple_build_call_internal (IFN_TRAP, 0);
}
+ gimple_call_set_ctrl_altering (g, true);
gimple_set_location (g, loc);
return g;
}
diff --git a/gcc/symtab-thunks.cc b/gcc/symtab-thunks.cc
index b043970..bd50c68 100644
--- a/gcc/symtab-thunks.cc
+++ b/gcc/symtab-thunks.cc
@@ -635,6 +635,7 @@ expand_thunk (cgraph_node *node, bool output_asm_thunks,
}
else
{
+ gimple_call_set_ctrl_altering (call, true);
gimple_call_set_tail (call, true);
cfun->tail_call_marked = true;
remove_edge (single_succ_edge (bb));
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index bbe0835..e39d947 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -821,8 +821,9 @@ handle_abnormal_edges (basic_block *dispatcher_bbs, basic_block for_bb,
else
{
tree arg = inner ? boolean_true_node : boolean_false_node;
- gimple *g = gimple_build_call_internal (IFN_ABNORMAL_DISPATCHER,
+ gcall *g = gimple_build_call_internal (IFN_ABNORMAL_DISPATCHER,
1, arg);
+ gimple_call_set_ctrl_altering (g, true);
gimple_stmt_iterator gsi = gsi_after_labels (*dispatcher);
gsi_insert_after (&gsi, g, GSI_NEW_STMT);
diff --git a/gcc/tree-cfgcleanup.cc b/gcc/tree-cfgcleanup.cc
index 3535a7e..b4869ae 100644
--- a/gcc/tree-cfgcleanup.cc
+++ b/gcc/tree-cfgcleanup.cc
@@ -220,9 +220,10 @@ cleanup_call_ctrl_altering_flag (basic_block bb, gimple *bb_end)
return;
int flags = gimple_call_flags (bb_end);
- if (((flags & (ECF_CONST | ECF_PURE))
- && !(flags & ECF_LOOPING_CONST_OR_PURE))
- || (flags & ECF_LEAF))
+ if (!(flags & ECF_NORETURN)
+ && (((flags & (ECF_CONST | ECF_PURE))
+ && !(flags & ECF_LOOPING_CONST_OR_PURE))
+ || (flags & ECF_LEAF)))
gimple_call_set_ctrl_altering (bb_end, false);
else
{
@@ -328,6 +329,10 @@ cleanup_control_flow_bb (basic_block bb)
gsi_remove (&gsi, true);
if (remove_fallthru_edge (bb->succs))
retval = true;
+ tree lhs = gimple_call_lhs (stmt);
+ if (!lhs
+ || !should_remove_lhs_p (lhs))
+ gimple_call_set_ctrl_altering (stmt, true);
}
return retval;
diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc
index 076ecd3e..ae8fa21 100644
--- a/gcc/tree-eh.cc
+++ b/gcc/tree-eh.cc
@@ -3321,7 +3321,7 @@ lower_resx (basic_block bb, gresx *stmt,
int lp_nr;
eh_region src_r, dst_r;
gimple_stmt_iterator gsi;
- gimple *x;
+ gcall *x;
tree fn, src_nr;
bool ret = false;
@@ -3346,6 +3346,7 @@ lower_resx (basic_block bb, gresx *stmt,
fn = builtin_decl_implicit (BUILT_IN_TRAP);
x = gimple_build_call (fn, 0);
+ gimple_call_set_ctrl_altering (x, true);
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
while (EDGE_COUNT (bb->succs) > 0)
@@ -3463,6 +3464,7 @@ lower_resx (basic_block bb, gresx *stmt,
fn = builtin_decl_implicit (BUILT_IN_UNWIND_RESUME);
x = gimple_build_call (fn, 1, var);
+ gimple_call_set_ctrl_altering (x, true);
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
}