diff options
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/c-common.c | 25 | ||||
-rw-r--r-- | gcc/c-common.h | 3 | ||||
-rw-r--r-- | gcc/c-semantics.c | 25 | ||||
-rw-r--r-- | gcc/expr.c | 6 | ||||
-rw-r--r-- | gcc/stmt.c | 67 | ||||
-rw-r--r-- | gcc/tree-inline.c | 6 | ||||
-rw-r--r-- | gcc/tree.h | 12 |
8 files changed, 124 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1b5008b0cba..a9eaf973d7f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2002-01-02 Alexandre Oliva <aoliva@redhat.com> + + * c-common.h (genrtl_expr_stmt_value): Declare. + * c-semantics.c (genrtl_goto_stmt): Redirect to... + (genrtl_goto_stmt_value): ... this new function. Pass new + argument down to expand_expr_stmt_value, taking + TREE_ADDRESSABLE into account. + * c-common.c (c_expand_expr): Mark the last EXPR_STMT of a + STMT_EXPR as addressable, i.e., one whose result we want. + * expr.c (expand_expr): Don't save expression statement value + of labeled_blocks or loop_exprs. + * stmt.c (expand_expr_stmt): Redirect to... + (expand_expr_stmt_value): ... this new function. Use new + argument to tell whether to save expression value. + (expand_end_stmt_expr): Reset last_expr_type and + last_expr_value if we don't have either. + * tree-inline.c (declare_return_variable): Mark its use + statement as addressable. + * tree.h: Document new use of TREE_ADDRESSABLE. + (expand_expr_stmt_value): Declare. + 2002-01-01 Joseph S. Myers <jsm28@cam.ac.uk> * configure.in: Prepend ${srcdir}/config/${cpu_type}/ instead of diff --git a/gcc/c-common.c b/gcc/c-common.c index d671e3bdf72..39ae17d9a8d 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -1,6 +1,6 @@ /* Subroutines shared by all languages that are variants of C. - Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -3418,6 +3418,27 @@ c_expand_expr (exp, target, tmode, modifier) STMT_EXPR. */ push_temp_slots (); rtl_expr = expand_start_stmt_expr (); + + /* If we want the result of this expression, find the last + EXPR_STMT in the COMPOUND_STMT and mark it as addressable. */ + if (target != const0_rtx + && TREE_CODE (STMT_EXPR_STMT (exp)) == COMPOUND_STMT + && TREE_CODE (COMPOUND_BODY (STMT_EXPR_STMT (exp))) == SCOPE_STMT) + { + tree expr = COMPOUND_BODY (STMT_EXPR_STMT (exp)); + tree last = TREE_CHAIN (expr); + + while (TREE_CHAIN (last)) + { + expr = last; + last = TREE_CHAIN (last); + } + + if (TREE_CODE (last) == SCOPE_STMT + && TREE_CODE (expr) == EXPR_STMT) + TREE_ADDRESSABLE (expr) = 1; + } + expand_stmt (STMT_EXPR_STMT (exp)); expand_end_stmt_expr (rtl_expr); result = expand_expr (rtl_expr, target, tmode, modifier); diff --git a/gcc/c-common.h b/gcc/c-common.h index 61b8f84428b..4c49b9fcddf 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -1,6 +1,6 @@ /* Definitions for c-common.c. Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998, - 1999, 2000, 2001 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -717,6 +717,7 @@ extern void add_c_tree_codes PARAMS ((void)); extern void genrtl_do_pushlevel PARAMS ((void)); extern void genrtl_goto_stmt PARAMS ((tree)); extern void genrtl_expr_stmt PARAMS ((tree)); +extern void genrtl_expr_stmt_value PARAMS ((tree, int)); extern void genrtl_decl_stmt PARAMS ((tree)); extern void genrtl_if_stmt PARAMS ((tree)); extern void genrtl_while_stmt PARAMS ((tree)); diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c index 86e2e8999bb..ef9ba333751 100644 --- a/gcc/c-semantics.c +++ b/gcc/c-semantics.c @@ -1,7 +1,7 @@ /* This file contains the definitions and documentation for the common tree codes used in the GNU C and C++ compilers (see c-common.def for the standard codes). - Copyright (C) 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. Written by Benjamin Chelf (chelf@codesourcery.com). This file is part of GCC. @@ -305,12 +305,27 @@ genrtl_goto_stmt (destination) expand_computed_goto (destination); } -/* Generate the RTL for EXPR, which is an EXPR_STMT. */ +/* Generate the RTL for EXPR, which is an EXPR_STMT. Provided just + for backward compatibility. genrtl_expr_stmt_value() should be + used for new code. */ -void +void genrtl_expr_stmt (expr) tree expr; { + genrtl_expr_stmt_value (expr, -1); +} + +/* Generate the RTL for EXPR, which is an EXPR_STMT. WANT_VALUE tells + whether to (1) save the value of the expression, (0) discard it or + (-1) use expr_stmts_for_value to tell. The use of -1 is + deprecated, and retained only for backward compatibility. */ + +void +genrtl_expr_stmt_value (expr, want_value) + tree expr; + int want_value; +{ if (expr != NULL_TREE) { emit_line_note (input_filename, lineno); @@ -319,7 +334,7 @@ genrtl_expr_stmt (expr) expand_start_target_temps (); if (expr != error_mark_node) - expand_expr_stmt (expr); + expand_expr_stmt_value (expr, want_value); if (stmts_are_full_exprs_p ()) expand_end_target_temps (); @@ -748,7 +763,7 @@ expand_stmt (t) break; case EXPR_STMT: - genrtl_expr_stmt (EXPR_STMT_EXPR (t)); + genrtl_expr_stmt_value (EXPR_STMT_EXPR (t), TREE_ADDRESSABLE (t)); break; case DECL_STMT: diff --git a/gcc/expr.c b/gcc/expr.c index 60c3431f73a..1388b6ff835 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -1,6 +1,6 @@ /* Convert tree expression to rtl instructions, for GNU compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001 Free Software Foundation, Inc. + 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -6453,7 +6453,7 @@ expand_expr (exp, target, tmode, modifier) case LABELED_BLOCK_EXPR: if (LABELED_BLOCK_BODY (exp)) - expand_expr_stmt (LABELED_BLOCK_BODY (exp)); + expand_expr_stmt_value (LABELED_BLOCK_BODY (exp), 0); /* Should perhaps use expand_label, but this is simpler and safer. */ do_pending_stack_adjust (); emit_label (label_rtx (LABELED_BLOCK_LABEL (exp))); @@ -6468,7 +6468,7 @@ expand_expr (exp, target, tmode, modifier) case LOOP_EXPR: push_temp_slots (); expand_start_loop (1); - expand_expr_stmt (TREE_OPERAND (exp, 0)); + expand_expr_stmt_value (TREE_OPERAND (exp, 0), 0); expand_end_loop (); pop_temp_slots (); diff --git a/gcc/stmt.c b/gcc/stmt.c index c87612aa3c3..16a3882ffd0 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -1,6 +1,6 @@ /* Expands front end tree to back end RTL for GNU C-Compiler Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -2182,16 +2182,37 @@ resolve_operand_name_1 (p, outputs, inputs) } /* Generate RTL to evaluate the expression EXP - and remember it in case this is the VALUE in a ({... VALUE; }) constr. */ + and remember it in case this is the VALUE in a ({... VALUE; }) constr. + Provided just for backward-compatibility. expand_expr_stmt_value() + should be used for new code. */ void expand_expr_stmt (exp) tree exp; { + expand_expr_stmt_value (exp, -1); +} + +/* Generate RTL to evaluate the expression EXP. WANT_VALUE tells + whether to (1) save the value of the expression, (0) discard it or + (-1) use expr_stmts_for_value to tell. The use of -1 is + deprecated, and retained only for backward compatibility. */ + +void +expand_expr_stmt_value (exp, want_value) + tree exp; + int want_value; +{ + rtx value; + tree type; + + if (want_value == -1) + want_value = expr_stmts_for_value != 0; + /* If -W, warn about statements with no side effects, except for an explicit cast to void (e.g. for assert()), and except inside a ({...}) where they may be useful. */ - if (expr_stmts_for_value == 0 && exp != error_mark_node) + if (! want_value && exp != error_mark_node) { if (! TREE_SIDE_EFFECTS (exp)) { @@ -2207,34 +2228,31 @@ expand_expr_stmt (exp) /* If EXP is of function type and we are expanding statements for value, convert it to pointer-to-function. */ - if (expr_stmts_for_value && TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE) + if (want_value && TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE) exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp); /* The call to `expand_expr' could cause last_expr_type and last_expr_value to get reset. Therefore, we set last_expr_value and last_expr_type *after* calling expand_expr. */ - last_expr_value = expand_expr (exp, - (expr_stmts_for_value - ? NULL_RTX : const0_rtx), - VOIDmode, 0); - last_expr_type = TREE_TYPE (exp); + value = expand_expr (exp, want_value ? NULL_RTX : const0_rtx, + VOIDmode, 0); + type = TREE_TYPE (exp); /* If all we do is reference a volatile value in memory, copy it to a register to be sure it is actually touched. */ - if (last_expr_value != 0 && GET_CODE (last_expr_value) == MEM - && TREE_THIS_VOLATILE (exp)) + if (value && GET_CODE (value) == MEM && TREE_THIS_VOLATILE (exp)) { - if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode) + if (TYPE_MODE (type) == VOIDmode) ; - else if (TYPE_MODE (TREE_TYPE (exp)) != BLKmode) - copy_to_reg (last_expr_value); + else if (TYPE_MODE (type) != BLKmode) + value = copy_to_reg (value); else { rtx lab = gen_label_rtx (); /* Compare the value with itself to reference it. */ - emit_cmp_and_jump_insns (last_expr_value, last_expr_value, EQ, - expand_expr (TYPE_SIZE (last_expr_type), + emit_cmp_and_jump_insns (value, value, EQ, + expand_expr (TYPE_SIZE (type), NULL_RTX, VOIDmode, 0), BLKmode, 0, lab); emit_label (lab); @@ -2243,13 +2261,19 @@ expand_expr_stmt (exp) /* If this expression is part of a ({...}) and is in memory, we may have to preserve temporaries. */ - preserve_temp_slots (last_expr_value); + preserve_temp_slots (value); /* Free any temporaries used to evaluate this expression. Any temporary used as a result of this expression will already have been preserved above. */ free_temp_slots (); + if (want_value) + { + last_expr_value = value; + last_expr_type = type; + } + emit_queue (); } @@ -2386,6 +2410,7 @@ expand_start_stmt_expr () start_sequence_for_rtl_expr (t); NO_DEFER_POP; expr_stmts_for_value++; + last_expr_value = NULL_RTX; return t; } @@ -2407,15 +2432,11 @@ expand_end_stmt_expr (t) { OK_DEFER_POP; - if (last_expr_type == 0) + if (! last_expr_value || ! last_expr_type) { - last_expr_type = void_type_node; last_expr_value = const0_rtx; + last_expr_type = void_type_node; } - else if (last_expr_value == 0) - /* There are some cases where this can happen, such as when the - statement is void type. */ - last_expr_value = const0_rtx; else if (GET_CODE (last_expr_value) != REG && ! CONSTANT_P (last_expr_value)) /* Remove any possible QUEUED. */ last_expr_value = protect_from_queue (last_expr_value, 0); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 6cd1fbb5e15..02ba7161b46 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1,5 +1,5 @@ /* Control and data flow functions for trees. - Copyright 2001 Free Software Foundation, Inc. + Copyright 2001, 2002 Free Software Foundation, Inc. Contributed by Alexandre Oliva <aoliva@redhat.com> This file is part of GNU CC. @@ -624,7 +624,9 @@ declare_return_variable (id, use_stmt) *use_stmt = build_stmt (EXPR_STMT, build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)), var)); - + + TREE_ADDRESSABLE (*use_stmt) = 1; + /* Build the declaration statement if FN does not return an aggregate. */ if (need_return_decl) diff --git a/gcc/tree.h b/gcc/tree.h index eee6663cb75..051aa2c5bf3 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1,6 +1,6 @@ /* Front-end tree definitions for GNU compiler. - Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 - Free Software Foundation, Inc. + Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -161,7 +161,9 @@ struct tree_common TREE_ADDRESSABLE in VAR_DECL, FUNCTION_DECL, FIELD_DECL, CONSTRUCTOR, LABEL_DECL, - ..._TYPE, IDENTIFIER_NODE + ..._TYPE, IDENTIFIER_NODE. + In a STMT_EXPR, it means we want the result of the enclosed + expression. static_flag: @@ -258,8 +260,7 @@ struct tree_common expressions, VAR_DECL, PARM_DECL, FIELD_DECL, FUNCTION_DECL, IDENTIFIER_NODE TYPE_BOUNDED in - ..._TYPE -*/ + ..._TYPE */ /* Define accessors for the fields that all tree nodes have (though some fields are not used for all kinds of nodes). */ @@ -2719,6 +2720,7 @@ extern void expand_fixups PARAMS ((rtx)); extern tree expand_start_stmt_expr PARAMS ((void)); extern tree expand_end_stmt_expr PARAMS ((tree)); extern void expand_expr_stmt PARAMS ((tree)); +extern void expand_expr_stmt_value PARAMS ((tree, int)); extern int warn_if_unused_value PARAMS ((tree)); extern void expand_decl_init PARAMS ((tree)); extern void clear_last_expr PARAMS ((void)); |