diff options
Diffstat (limited to 'gcc/tree-cfg.cc')
-rw-r--r-- | gcc/tree-cfg.cc | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 5bcf781..53be0c2 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); @@ -1305,7 +1306,7 @@ end_recording_case_labels (void) Otherwise return NULL. */ -static tree +tree get_cases_for_edge (edge e, gswitch *t) { tree *slot; @@ -4166,6 +4167,8 @@ verify_gimple_assign_binary (gassign *stmt) case ROUND_MOD_EXPR: case RDIV_EXPR: case EXACT_DIV_EXPR: + case BIT_IOR_EXPR: + case BIT_XOR_EXPR: /* Disallow pointer and offset types for many of the binary gimple. */ if (POINTER_TYPE_P (lhs_type) || TREE_CODE (lhs_type) == OFFSET_TYPE) @@ -4181,9 +4184,23 @@ verify_gimple_assign_binary (gassign *stmt) case MIN_EXPR: case MAX_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: + /* Continue with generic binary expression handling. */ + break; + case BIT_AND_EXPR: + if (POINTER_TYPE_P (lhs_type) + && TREE_CODE (rhs2) == INTEGER_CST) + break; + /* Disallow pointer and offset types for many of the binary gimple. */ + if (POINTER_TYPE_P (lhs_type) + || TREE_CODE (lhs_type) == OFFSET_TYPE) + { + error ("invalid types for %qs", code_name); + debug_generic_expr (lhs_type); + debug_generic_expr (rhs1_type); + debug_generic_expr (rhs2_type); + return true; + } /* Continue with generic binary expression handling. */ break; @@ -9819,16 +9836,12 @@ execute_fixup_cfg (void) int flags = gimple_call_flags (stmt); if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE)) { - if (gimple_purge_dead_abnormal_call_edges (bb)) - todo |= TODO_cleanup_cfg; - if (gimple_in_ssa_p (cfun)) { todo |= TODO_update_ssa | TODO_cleanup_cfg; update_stmt (stmt); } } - if (flags & ECF_NORETURN && fixup_noreturn_call (stmt)) todo |= TODO_cleanup_cfg; @@ -9858,10 +9871,15 @@ execute_fixup_cfg (void) } } - if (maybe_clean_eh_stmt (stmt) + gsi_next (&gsi); + } + if (gimple *last = last_stmt (bb)) + { + if (maybe_clean_eh_stmt (last) && gimple_purge_dead_eh_edges (bb)) todo |= TODO_cleanup_cfg; - gsi_next (&gsi); + if (gimple_purge_dead_abnormal_call_edges (bb)) + todo |= TODO_cleanup_cfg; } /* If we have a basic block with no successors that does not @@ -9878,16 +9896,16 @@ execute_fixup_cfg (void) { if (stmt && is_gimple_call (stmt)) gimple_call_set_ctrl_altering (stmt, false); - tree fndecl = builtin_decl_unreachable (); - stmt = gimple_build_call (fndecl, 0); + stmt = gimple_build_builtin_unreachable (UNKNOWN_LOCATION); gimple_stmt_iterator gsi = gsi_last_bb (bb); gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); if (!cfun->after_inlining) - { - gcall *call_stmt = dyn_cast <gcall *> (stmt); - node->create_edge (cgraph_node::get_create (fndecl), - call_stmt, bb->count); - } + if (tree fndecl = gimple_call_fndecl (stmt)) + { + gcall *call_stmt = dyn_cast <gcall *> (stmt); + node->create_edge (cgraph_node::get_create (fndecl), + call_stmt, bb->count); + } } } } |