/* Build a label for the new block which will contain the
factored computed goto. */
- factored_label_decl = create_artificial_label ();
+ factored_label_decl = create_artificial_label (UNKNOWN_LOCATION);
factored_computed_goto_label
= gimple_build_label (factored_label_decl);
gsi_insert_after (&new_gsi, factored_computed_goto_label,
if (stmt && gimple_code (stmt) == GIMPLE_COND)
{
+ location_t loc = gimple_location (stmt);
tree cond;
bool zerop, onep;
fold_defer_overflow_warnings ();
- cond = fold_binary (gimple_cond_code (stmt), boolean_type_node,
+ cond = fold_binary_loc (loc, gimple_cond_code (stmt), boolean_type_node,
gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
if (cond)
{
static void
assign_discriminator (location_t locus, basic_block bb)
{
- gimple to_stmt;
+ gimple first_in_to_bb, last_in_to_bb;
if (locus == 0 || bb->discriminator != 0)
return;
- to_stmt = first_non_label_stmt (bb);
- if (to_stmt && same_line_p (locus, gimple_location (to_stmt)))
+ first_in_to_bb = first_non_label_stmt (bb);
+ last_in_to_bb = last_stmt (bb);
+ if ((first_in_to_bb && same_line_p (locus, gimple_location (first_in_to_bb)))
+ || (last_in_to_bb && same_line_p (locus, gimple_location (last_in_to_bb))))
bb->discriminator = next_discriminator_for_locus (locus);
}
{
gimple stmt = gsi_stmt (gsi);
+ if (gimple_no_warning_p (stmt)) return false;
+
if (gimple_has_location (stmt))
{
location_t loc = gimple_location (stmt);
if (LOCATION_LINE (loc) > 0)
{
- warning (OPT_Wunreachable_code, "%Hwill never be executed", &loc);
+ warning_at (loc, OPT_Wunreachable_code, "will never be executed");
return true;
}
}
loop above, so the last statement we process is the first statement
in the block. */
if (loc > BUILTINS_LOCATION && LOCATION_LINE (loc) > 0)
- warning (OPT_Wunreachable_code, "%Hwill never be executed", &loc);
+ warning_at (loc, OPT_Wunreachable_code, "will never be executed");
remove_phi_nodes_and_edges_for_unreachable_block (bb);
bb->il.gimple = NULL;
gcc_assert (result == gimple_phi_result (phi));
- add_phi_arg (phi, arg, new_edge);
+ add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm));
}
redirect_edge_var_map_clear (old_edge);
if (addr)
{
debug_generic_expr (addr);
- inform (input_location, "in statement");
+ inform (gimple_location (gsi_stmt (*gsi)), "in statement");
debug_gimple_stmt (stmt);
return true;
}
new_phi = create_phi_node (var, bb);
SSA_NAME_DEF_STMT (var) = new_phi;
gimple_phi_set_result (phi, make_ssa_name (SSA_NAME_VAR (var), phi));
- add_phi_arg (new_phi, gimple_phi_result (phi), fallthru);
+ add_phi_arg (new_phi, gimple_phi_result (phi), fallthru,
+ UNKNOWN_LOCATION);
}
/* Add the arguments we have stored on edges. */
}
}
- label = create_artificial_label ();
+ label = create_artificial_label (UNKNOWN_LOCATION);
stmt = gimple_build_label (label);
gsi_insert_before (&s, stmt, GSI_NEW_STMT);
return label;
gsi = gsi_last_bb (bb);
stmt = gsi_end_p (gsi) ? NULL : gsi_stmt (gsi);
- switch (stmt ? gimple_code (stmt) : ERROR_MARK)
+ switch (stmt ? gimple_code (stmt) : GIMPLE_ERROR_MARK)
{
case GIMPLE_COND:
/* For COND_EXPR, we only need to redirect the edge. */
phi = gsi_stmt (psi);
phi_copy = gsi_stmt (psi_copy);
def = PHI_ARG_DEF_FROM_EDGE (phi, e);
- add_phi_arg (phi_copy, def, e_copy);
+ add_phi_arg (phi_copy, def, e_copy,
+ gimple_phi_arg_location_from_edge (phi, e));
}
}
m = XNEW (struct tree_map);
m->hash = DECL_UID (decl);
m->base.from = decl;
- m->to = create_artificial_label ();
+ m->to = create_artificial_label (UNKNOWN_LOCATION);
LABEL_DECL_UID (m->to) = LABEL_DECL_UID (decl);
if (LABEL_DECL_UID (m->to) >= cfun->cfg->last_label_uid)
cfun->cfg->last_label_uid = LABEL_DECL_UID (m->to) + 1;
phi1 = gsi_stmt (psi1);
phi2 = gsi_stmt (psi2);
def = PHI_ARG_DEF (phi2, e2->dest_idx);
- add_phi_arg (phi1, def, e);
+ add_phi_arg (phi1, def, e, gimple_phi_arg_location_from_edge (phi2, e2));
}
}
tree type, tree a, tree b, tree c)
{
tree ret;
+ location_t loc = gimple_location (gsi_stmt (*gsi));
- ret = fold_build3 (code, type, a, b, c);
+ ret = fold_build3_loc (loc, code, type, a, b, c);
STRIP_NOPS (ret);
return force_gimple_operand_gsi (gsi, ret, true, NULL, true,
{
tree ret;
- ret = fold_build2 (code, type, a, b);
+ ret = fold_build2_loc (gimple_location (gsi_stmt (*gsi)), code, type, a, b);
STRIP_NOPS (ret);
return force_gimple_operand_gsi (gsi, ret, true, NULL, true,
{
tree ret;
- ret = fold_build1 (code, type, a);
+ ret = fold_build1_loc (gimple_location (gsi_stmt (*gsi)), code, type, a);
STRIP_NOPS (ret);
return force_gimple_operand_gsi (gsi, ret, true, NULL, true,
}
if (location == UNKNOWN_LOCATION)
location = cfun->function_end_locus;
- warning (0, "%H%<noreturn%> function does return", &location);
+ warning_at (location, 0, "%<noreturn%> function does return");
}
/* If we see "return;" in some basic block, then we do reach the end
&& !TREE_THIS_VOLATILE (cfun->decl)
&& EDGE_COUNT (EXIT_BLOCK_PTR->preds) == 0
&& !lang_hooks.missing_noreturn_ok_p (cfun->decl))
- warning (OPT_Wmissing_noreturn, "%Jfunction might be possible candidate "
- "for attribute %<noreturn%>",
- cfun->decl);
+ warning_at (DECL_SOURCE_LOCATION (cfun->decl), OPT_Wmissing_noreturn,
+ "function might be possible candidate "
+ "for attribute %<noreturn%>");
return 0;
}
0 /* todo_flags_finish */
}
};
+
+
+/* Walk a gimplified function and warn for functions whose return value is
+ ignored and attribute((warn_unused_result)) is set. This is done before
+ inlining, so we don't have to worry about that. */
+
+static void
+do_warn_unused_result (gimple_seq seq)
+{
+ tree fdecl, ftype;
+ gimple_stmt_iterator i;
+
+ for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+ {
+ gimple g = gsi_stmt (i);
+
+ switch (gimple_code (g))
+ {
+ case GIMPLE_BIND:
+ do_warn_unused_result (gimple_bind_body (g));
+ break;
+ case GIMPLE_TRY:
+ do_warn_unused_result (gimple_try_eval (g));
+ do_warn_unused_result (gimple_try_cleanup (g));
+ break;
+ case GIMPLE_CATCH:
+ do_warn_unused_result (gimple_catch_handler (g));
+ break;
+ case GIMPLE_EH_FILTER:
+ do_warn_unused_result (gimple_eh_filter_failure (g));
+ break;
+
+ case GIMPLE_CALL:
+ if (gimple_call_lhs (g))
+ break;
+
+ /* This is a naked call, as opposed to a GIMPLE_CALL with an
+ LHS. All calls whose value is ignored should be
+ represented like this. Look for the attribute. */
+ fdecl = gimple_call_fndecl (g);
+ ftype = TREE_TYPE (TREE_TYPE (gimple_call_fn (g)));
+
+ if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
+ {
+ location_t loc = gimple_location (g);
+
+ if (fdecl)
+ warning_at (loc, OPT_Wunused_result,
+ "ignoring return value of %qD, "
+ "declared with attribute warn_unused_result",
+ fdecl);
+ else
+ warning_at (loc, OPT_Wunused_result,
+ "ignoring return value of function "
+ "declared with attribute warn_unused_result");
+ }
+ break;
+
+ default:
+ /* Not a container, not a call, or a call whose value is used. */
+ break;
+ }
+ }
+}
+
+static unsigned int
+run_warn_unused_result (void)
+{
+ do_warn_unused_result (gimple_body (current_function_decl));
+ return 0;
+}
+
+static bool
+gate_warn_unused_result (void)
+{
+ return flag_warn_unused_result;
+}
+
+struct gimple_opt_pass pass_warn_unused_result =
+{
+ {
+ GIMPLE_PASS,
+ "warn_unused_result", /* name */
+ gate_warn_unused_result, /* gate */
+ run_warn_unused_result, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+ }
+};
+