X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fstmt.c;h=fa87140fe48afc9c768d65e284ddea32e3591d81;hb=bf48cae7ca8c714c83bf71af83fad8408163a577;hp=7e5ff1abb3b39c1980c1962e458e8ac29a53e33e;hpb=194dd2f9992ba407bef76d8b2370e32c8494a6af;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/stmt.c b/gcc/stmt.c index 7e5ff1abb3b..fa87140fe48 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -204,8 +204,6 @@ struct nesting GTY(()) /* Chain of labels defined inside this binding contour. For contours that have stack levels or cleanups. */ struct label_chain *label_chain; - /* Number of function calls seen, as of start of this block. */ - int n_function_calls; /* Nonzero if this is associated with an EH region. */ int exception_region; /* The saved target_temp_slot_level from our outer block. @@ -368,10 +366,9 @@ struct stmt_status GTY(()) always compute a value for each expr-stmt in case it is the last one. */ int x_expr_stmts_for_value; - /* Filename and line number of last line-number note, - whether we actually emitted it or not. */ - const char *x_emit_filename; - int x_emit_lineno; + /* Location of last line-number note, whether we actually + emitted it or not. */ + location_t x_emit_locus; struct goto_fixup *x_goto_fixup_chain; }; @@ -387,8 +384,7 @@ struct stmt_status GTY(()) #define last_expr_type (cfun->stmt->x_last_expr_type) #define last_expr_value (cfun->stmt->x_last_expr_value) #define expr_stmts_for_value (cfun->stmt->x_expr_stmts_for_value) -#define emit_filename (cfun->stmt->x_emit_filename) -#define emit_lineno (cfun->stmt->x_emit_lineno) +#define emit_locus (cfun->stmt->x_emit_locus) #define goto_fixup_chain (cfun->stmt->x_goto_fixup_chain) /* Nonzero if we are using EH to handle cleanups. */ @@ -415,7 +411,7 @@ static void expand_null_return_1 PARAMS ((rtx)); static enum br_predictor return_prediction PARAMS ((rtx)); static void expand_value_return PARAMS ((rtx)); static int tail_recursion_args PARAMS ((tree, tree)); -static void expand_cleanups PARAMS ((tree, tree, int, int)); +static void expand_cleanups PARAMS ((tree, int, int)); static void check_seenlabel PARAMS ((void)); static void do_jump_if_equal PARAMS ((rtx, rtx, rtx, int)); static int estimate_case_costs PARAMS ((case_node_ptr)); @@ -476,8 +472,8 @@ set_file_and_line_for_stmt (file, line) update it. */ if (cfun->stmt) { - emit_filename = file; - emit_lineno = line; + emit_locus.file = file; + emit_locus.line = line; } } @@ -512,6 +508,29 @@ label_rtx (label) return DECL_RTL (label); } +/* As above, but also put it on the forced-reference list of the + function that contains it. */ +rtx +force_label_rtx (label) + tree label; +{ + rtx ref = label_rtx (label); + tree function = decl_function_context (label); + struct function *p; + + if (!function) + abort (); + + if (function != current_function_decl + && function != inline_function_decl) + p = find_function_data (function); + else + p = cfun; + + p->expr->x_forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref, + p->expr->x_forced_labels); + return ref; +} /* Add an unconditional jump to LABEL as the next sequential instruction. */ @@ -735,7 +754,7 @@ expand_goto_internal (body, label, last_insn) /* Execute the cleanups for blocks we are exiting. */ if (block->data.block.cleanups != 0) { - expand_cleanups (block->data.block.cleanups, NULL_TREE, 1, 1); + expand_cleanups (block->data.block.cleanups, 1, 1); do_pending_stack_adjust (); } } @@ -1026,7 +1045,7 @@ fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in) if (TREE_ADDRESSABLE (lists) && TREE_VALUE (lists) != 0) { - expand_cleanups (TREE_VALUE (lists), NULL_TREE, 1, 1); + expand_cleanups (TREE_VALUE (lists), 1, 1); /* Pop any pushes done in the cleanups, in case function is about to return. */ do_pending_stack_adjust (); @@ -1089,7 +1108,7 @@ fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in) start_sequence (); (*lang_hooks.decls.pushlevel) (0); (*lang_hooks.decls.set_block) (f->context); - expand_cleanups (TREE_VALUE (lists), NULL_TREE, 1, 1); + expand_cleanups (TREE_VALUE (lists), 1, 1); do_pending_stack_adjust (); cleanup_insns = get_insns (); (*lang_hooks.decls.poplevel) (1, 0, 0); @@ -2176,11 +2195,10 @@ expand_expr_stmt_value (exp, want_value, maybe_last) { if (! TREE_SIDE_EFFECTS (exp)) { - if ((extra_warnings || warn_unused_value) + if (warn_unused_value && !(TREE_CODE (exp) == CONVERT_EXPR && VOID_TYPE_P (TREE_TYPE (exp)))) - warning_with_file_and_line (emit_filename, emit_lineno, - "statement with no effect"); + warning ("%Hstatement with no effect", &emit_locus); } else if (warn_unused_value) warn_if_unused_value (exp); @@ -2340,8 +2358,7 @@ warn_if_unused_value (exp) if (TREE_SIDE_EFFECTS (exp)) return 0; - warning_with_file_and_line (emit_filename, emit_lineno, - "value computed is not used"); + warning ("%Hvalue computed is not used", &emit_locus); return 1; } } @@ -3350,15 +3367,15 @@ tail_recursion_args (actuals, formals) else { rtx tmp = argvec[i]; - + int unsignedp = TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a))); + promote_mode(TREE_TYPE (TREE_VALUE (a)), GET_MODE (tmp), + &unsignedp, 0); if (DECL_MODE (f) != GET_MODE (DECL_RTL (f))) { tmp = gen_reg_rtx (DECL_MODE (f)); - convert_move (tmp, argvec[i], - TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a)))); + convert_move (tmp, argvec[i], unsignedp); } - convert_move (DECL_RTL (f), tmp, - TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a)))); + convert_move (DECL_RTL (f), tmp, unsignedp); } } @@ -3418,7 +3435,6 @@ expand_start_bindings_and_block (flags, block) thisblock->depth = ++nesting_depth; thisblock->data.block.stack_level = 0; thisblock->data.block.cleanups = 0; - thisblock->data.block.n_function_calls = 0; thisblock->data.block.exception_region = 0; thisblock->data.block.block_target_temp_slot_level = target_temp_slot_level; @@ -3740,8 +3756,7 @@ expand_end_bindings (vars, mark_ends, dont_jump_in) /* If necessary, make handlers for nonlocal gotos taking place in the function calls in this block. */ - if (function_call_count != thisblock->data.block.n_function_calls - && nonlocal_labels + if (function_call_count != 0 && nonlocal_labels /* Make handler for outermost block if there were any nonlocal gotos to this function. */ && (thisblock->next == 0 ? current_function_has_nonlocal_label @@ -3795,7 +3810,7 @@ expand_end_bindings (vars, mark_ends, dont_jump_in) reachable = (! insn || GET_CODE (insn) != BARRIER); /* Do the cleanups. */ - expand_cleanups (thisblock->data.block.cleanups, NULL_TREE, 0, reachable); + expand_cleanups (thisblock->data.block.cleanups, 0, reachable); if (reachable) do_pending_stack_adjust (); @@ -3924,6 +3939,7 @@ expand_decl (decl) && !(flag_float_store && TREE_CODE (type) == REAL_TYPE) && ! TREE_THIS_VOLATILE (decl) + && ! DECL_NONLOCAL (decl) && (DECL_REGISTER (decl) || optimize)) { /* Automatic variable that can go in a register. */ @@ -3943,7 +3959,7 @@ expand_decl (decl) /* If something wants our address, try to use ADDRESSOF. */ if (TREE_ADDRESSABLE (decl)) - put_var_into_stack (decl); + put_var_into_stack (decl, /*rescan=*/false); } else if (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST @@ -4271,11 +4287,6 @@ expand_anon_union_decl (decl, cleanup, decl_elts) /* Expand a list of cleanups LIST. Elements may be expressions or may be nested lists. - If DONT_DO is nonnull, then any list-element - whose TREE_PURPOSE matches DONT_DO is omitted. - This is sometimes used to avoid a cleanup associated with - a value that is being returned out of the scope. - If IN_FIXUP is nonzero, we are generating this cleanup for a fixup goto and handle protection regions specially in that case. @@ -4283,48 +4294,44 @@ expand_anon_union_decl (decl, cleanup, decl_elts) code about this finalization. */ static void -expand_cleanups (list, dont_do, in_fixup, reachable) +expand_cleanups (list, in_fixup, reachable) tree list; - tree dont_do; int in_fixup; int reachable; { tree tail; for (tail = list; tail; tail = TREE_CHAIN (tail)) - if (dont_do == 0 || TREE_PURPOSE (tail) != dont_do) + if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST) + expand_cleanups (TREE_VALUE (tail), in_fixup, reachable); + else { - if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST) - expand_cleanups (TREE_VALUE (tail), dont_do, in_fixup, reachable); - else - { - if (! in_fixup && using_eh_for_cleanups_p) - expand_eh_region_end_cleanup (TREE_VALUE (tail)); + if (! in_fixup && using_eh_for_cleanups_p) + expand_eh_region_end_cleanup (TREE_VALUE (tail)); - if (reachable && !CLEANUP_EH_ONLY (tail)) + if (reachable && !CLEANUP_EH_ONLY (tail)) + { + /* Cleanups may be run multiple times. For example, + when exiting a binding contour, we expand the + cleanups associated with that contour. When a goto + within that binding contour has a target outside that + contour, it will expand all cleanups from its scope to + the target. Though the cleanups are expanded multiple + times, the control paths are non-overlapping so the + cleanups will not be executed twice. */ + + /* We may need to protect from outer cleanups. */ + if (in_fixup && using_eh_for_cleanups_p) { - /* Cleanups may be run multiple times. For example, - when exiting a binding contour, we expand the - cleanups associated with that contour. When a goto - within that binding contour has a target outside that - contour, it will expand all cleanups from its scope to - the target. Though the cleanups are expanded multiple - times, the control paths are non-overlapping so the - cleanups will not be executed twice. */ - - /* We may need to protect from outer cleanups. */ - if (in_fixup && using_eh_for_cleanups_p) - { - expand_eh_region_start (); - - expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0); + expand_eh_region_start (); - expand_eh_region_end_fixup (TREE_VALUE (tail)); - } - else - expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0); + expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0); - free_temp_slots (); + expand_eh_region_end_fixup (TREE_VALUE (tail)); } + else + expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0); + + free_temp_slots (); } } } @@ -4496,10 +4503,13 @@ check_seenlabel () /* If insn is zero, then there must have been a syntax error. */ if (insn) - warning_with_file_and_line (NOTE_SOURCE_FILE (insn), - NOTE_LINE_NUMBER (insn), - "unreachable code at beginning of %s", - case_stack->data.case_stmt.printname); + { + location_t locus; + locus.file = NOTE_SOURCE_FILE (insn); + locus.line = NOTE_LINE_NUMBER (insn); + warning ("%Hunreachable code at beginning of %s", &locus, + case_stack->data.case_stmt.printname); + } break; } } @@ -5505,6 +5515,7 @@ expand_end_case_type (orig_index, orig_type) else if (CASE_USE_BIT_TESTS && ! TREE_CONSTANT (index_expr) && compare_tree_int (range, GET_MODE_BITSIZE (word_mode)) < 0 + && compare_tree_int (range, 0) > 0 && lshift_cheap_p () && ((uniq == 1 && count >= 3) || (uniq == 2 && count >= 5)