From 3a5b9284da6acc309118a04dcba3a1cbca2ecdd4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 21 Jun 2004 02:15:29 -0700 Subject: [PATCH] c-common.c (verify_sequence_points): Export. * c-common.c (verify_sequence_points): Export. (c_expand_expr_stmt): Move to c-typeck.c. * c-common.h (c_expand_expr_stmt): Remove. (verify_sequence_points): Declare. * c-mudflap.c (mflang_flush_calls): Use c_finish_expr_stmt. * c-parse.in (for_init_stmt, stmt): Likewise. * c-tree.h (c_finish_expr_stmt): Declare. (c_tree_expr_nonnegative_p): Remove. * c-typeck.c (c_tree_expr_nonnegative_p): Remove. (build_conditional_expr, build_binary_op): Use tree_expr_nonnegative_p. (emit_side_effect_warnings): New. (c_finish_expr_stmt): Rename from c_expand_expr_stmt. Use it. (c_finish_stmt_expr): Work without EXPR_STMT. Handle eh regions. Use emit_side_effect_warnings. (push_cleanup): Copy STATEMENT_LIST_STMT_EXPR. * fold-const.c (tree_expr_nonnegative_p): Handle TARGET_EXPR. * gimplify.c (gimplify_modify_expr): Don't discard TARGET_EXPR with void initializer. (gimplify_target_expr): Handle void BIND_EXPR initializer. * tree-inline.c (estimate_num_insns_1): Fix type lookup for INIT_EXPR and MODIFY_EXPR. * objc/objc-act.c (build_module_descriptor): Use add_stmt instead of c_expand_expr_stmt. cp/ * semantics.c (finish_expr_stmt): Call verify_sequence_points. testsuite/ * gcc.dg/tree-ssa/20030714-1.c: Rename variables to avoid merging && to BIT_FIELD_REF. From-SVN: r83429 --- gcc/ChangeLog | 26 +++ gcc/c-common.c | 29 +--- gcc/c-common.h | 3 +- gcc/c-mudflap.c | 2 +- gcc/c-parse.in | 4 +- gcc/c-tree.h | 2 +- gcc/c-typeck.c | 185 ++++++++++++++------- gcc/cp/ChangeLog | 4 + gcc/cp/semantics.c | 6 +- gcc/fold-const.c | 31 ++++ gcc/gimplify.c | 41 +++-- gcc/objc/objc-act.c | 2 +- gcc/testsuite/ChangeLog | 5 + gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c | 9 +- gcc/tree-inline.c | 5 +- 15 files changed, 239 insertions(+), 115 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e2d9993f9e0e..77f8f98e00c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,29 @@ +2004-06-21 Richard Henderson + + * c-common.c (verify_sequence_points): Export. + (c_expand_expr_stmt): Move to c-typeck.c. + * c-common.h (c_expand_expr_stmt): Remove. + (verify_sequence_points): Declare. + * c-mudflap.c (mflang_flush_calls): Use c_finish_expr_stmt. + * c-parse.in (for_init_stmt, stmt): Likewise. + * c-tree.h (c_finish_expr_stmt): Declare. + (c_tree_expr_nonnegative_p): Remove. + * c-typeck.c (c_tree_expr_nonnegative_p): Remove. + (build_conditional_expr, build_binary_op): Use tree_expr_nonnegative_p. + (emit_side_effect_warnings): New. + (c_finish_expr_stmt): Rename from c_expand_expr_stmt. Use it. + (c_finish_stmt_expr): Work without EXPR_STMT. Handle eh regions. + Use emit_side_effect_warnings. + (push_cleanup): Copy STATEMENT_LIST_STMT_EXPR. + * fold-const.c (tree_expr_nonnegative_p): Handle TARGET_EXPR. + * gimplify.c (gimplify_modify_expr): Don't discard TARGET_EXPR + with void initializer. + (gimplify_target_expr): Handle void BIND_EXPR initializer. + * tree-inline.c (estimate_num_insns_1): Fix type lookup for + INIT_EXPR and MODIFY_EXPR. + * objc/objc-act.c (build_module_descriptor): Use add_stmt + instead of c_expand_expr_stmt. + 2004-06-21 Paolo Bonzini * fold-const.c (fold_cond_expr_with_comparison): diff --git a/gcc/c-common.c b/gcc/c-common.c index a982852482d1..79d9d9ac8597 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -1247,7 +1247,6 @@ static int warning_candidate_p (tree); static void warn_for_collisions (struct tlist *); static void warn_for_collisions_1 (tree, tree, struct tlist *, int); static struct tlist *new_tlist (struct tlist *, tree, tree); -static void verify_sequence_points (tree); /* Create a new struct tlist and fill in its fields. */ static struct tlist * @@ -1586,7 +1585,7 @@ verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp, /* Try to warn for undefined behavior in EXPR due to missing sequence points. */ -static void +void verify_sequence_points (tree expr) { struct tlist *before_sp = 0, *after_sp = 0; @@ -1603,32 +1602,6 @@ verify_sequence_points (tree expr) warn_for_collisions (after_sp); obstack_free (&tlist_obstack, tlist_firstobj); } - -tree -c_expand_expr_stmt (tree expr) -{ - /* Do default conversion if safe and possibly important, - in case within ({...}). */ - if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE - && (flag_isoc99 || lvalue_p (expr))) - || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE) - expr = default_conversion (expr); - - if (warn_sequence_point) - verify_sequence_points (expr); - - if (TREE_TYPE (expr) != error_mark_node - && !COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (expr)) - && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE) - error ("expression statement has incomplete type"); - - /* As tempting as it might be, we can't diagnose statement with no - effect yet. We have to wait until after statement expressions - have been parsed, and that process modifies the trees we are - creating here. */ - - return add_stmt (build_stmt (EXPR_STMT, expr)); -} /* Validate the expression after `case' and apply default promotions. */ diff --git a/gcc/c-common.h b/gcc/c-common.h index f8d087b8dbd8..27733aa7c5c3 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -859,7 +859,6 @@ extern void binary_op_error (enum tree_code); #define my_friendly_assert(EXP, N) (void) \ (((EXP) == 0) ? (fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0) : 0) -extern tree c_expand_expr_stmt (tree); /* Validate the expression after `case' and apply default promotions. */ extern tree check_case_value (tree); extern tree fix_string_type (tree); @@ -1097,6 +1096,8 @@ extern tree c_walk_subtrees (tree*, int*, walk_tree_fn, void*, void*); extern void c_warn_unused_result (tree *); +extern void verify_sequence_points (tree); + /* In c-gimplify.c */ extern void c_genericize (tree); extern int c_gimplify_expr (tree *, tree *, tree *); diff --git a/gcc/c-mudflap.c b/gcc/c-mudflap.c index 78523e960a07..af1ade9b2dea 100644 --- a/gcc/c-mudflap.c +++ b/gcc/c-mudflap.c @@ -85,7 +85,7 @@ mflang_flush_calls (tree enqueued_call_stmt_chain) mf_mark (current_function_decl); cs = c_begin_compound_stmt (true); - c_expand_expr_stmt (enqueued_call_stmt_chain); + c_finish_expr_stmt (enqueued_call_stmt_chain); add_stmt (c_end_compound_stmt (cs, true)); finish_function (); diff --git a/gcc/c-parse.in b/gcc/c-parse.in index 176e97a7281c..ce8829a0321d 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -2210,7 +2210,7 @@ select_or_iter_stmt: for_init_stmt: xexpr ';' - { add_stmt (build_stmt (EXPR_STMT, $1)); } + { c_finish_expr_stmt ($1); } | decl { check_for_loop_decls (); } ; @@ -2226,7 +2226,7 @@ stmt: compstmt { stmt_count++; add_stmt ($1); } | expr ';' - { stmt_count++; c_expand_expr_stmt ($1); } + { stmt_count++; c_finish_expr_stmt ($1); } | c99_block_start select_or_iter_stmt { add_stmt (c_end_compound_stmt ($1, flag_isoc99)); } | BREAK ';' diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 92a5b7144784..03d84dd6672c 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -227,7 +227,6 @@ extern tree build_indirect_ref (tree, const char *); extern tree build_array_ref (tree, tree); extern tree build_external_ref (tree, int); extern tree parser_build_binary_op (enum tree_code, tree, tree); -extern int c_tree_expr_nonnegative_p (tree); extern void readonly_error (tree, const char *); extern tree build_conditional_expr (tree, tree, tree); extern tree build_compound_expr (tree); @@ -272,6 +271,7 @@ extern void c_finish_for_stmt_incr (tree, tree); extern void c_finish_for_stmt (tree, tree); extern tree c_begin_stmt_expr (void); extern tree c_finish_stmt_expr (tree); +extern void c_finish_expr_stmt (tree); extern tree build_offsetof (tree, tree); /* Set to 0 at beginning of a function definition, set to 1 if diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 99bb78d7c1d7..91423dda0c77 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -46,6 +46,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "ggc.h" #include "target.h" #include "tree-iterator.h" +#include "tree-gimple.h" /* Nonzero if we've already printed a "missing braces around initializer" @@ -2201,17 +2202,6 @@ parser_build_binary_op (enum tree_code code, tree arg1, tree arg2) return result; } - -/* Return true if `t' is known to be non-negative. */ - -int -c_tree_expr_nonnegative_p (tree t) -{ - if (TREE_CODE (t) == STMT_EXPR) - t = expr_last (STMT_EXPR_STMT (t)); - return tree_expr_nonnegative_p (t); -} - /* Return a tree for the difference of pointers OP0 and OP1. The resulting tree has type int. */ @@ -2810,8 +2800,8 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) /* Do not warn if the signed quantity is an unsuffixed integer literal (or some static constant expression involving such literals) and it is non-negative. */ - else if ((unsigned_op2 && c_tree_expr_nonnegative_p (op1)) - || (unsigned_op1 && c_tree_expr_nonnegative_p (op2))) + else if ((unsigned_op2 && tree_expr_nonnegative_p (op1)) + || (unsigned_op1 && tree_expr_nonnegative_p (op2))) /* OK */; else warning ("signed and unsigned type in conditional expression"); @@ -6657,7 +6647,61 @@ c_finish_for_stmt (tree body, tree for_stmt) FOR_BODY (for_stmt) = body; } -/* Create a statement expression. */ +/* A helper routine for c_finish_expr_stmt and c_finish_stmt_expr. */ + +static void +emit_side_effect_warnings (tree expr) +{ + if (!TREE_SIDE_EFFECTS (expr)) + { + if (!VOID_TYPE_P (TREE_TYPE (expr)) && !TREE_NO_WARNING (expr)) + warning ("%Hstatement with no effect", + EXPR_LOCUS (expr) ? EXPR_LOCUS (expr) : &input_location); + } + else if (warn_unused_value) + warn_if_unused_value (expr, input_location); +} + +/* Emit an expression as a statement. */ + +void +c_finish_expr_stmt (tree expr) +{ + if (!expr) + return; + + /* Do default conversion if safe and possibly important, + in case within ({...}). */ + if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE + && (flag_isoc99 || lvalue_p (expr))) + || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE) + expr = default_conversion (expr); + + if (warn_sequence_point) + verify_sequence_points (expr); + + if (TREE_TYPE (expr) != error_mark_node + && !COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (expr)) + && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE) + error ("expression statement has incomplete type"); + + /* If we're not processing a statement expression, warn about unused values. + Warnings for statement expressions will be emitted later, once we figure + out which is the result. */ + if (!STATEMENT_LIST_STMT_EXPR (cur_stmt_list) + && (extra_warnings || warn_unused_value)) + emit_side_effect_warnings (expr); + + /* If the expression is not of a type to which we cannot assign a line + number, wrap the thing in a no-op NOP_EXPR. */ + if (DECL_P (expr) || TREE_CODE_CLASS (TREE_CODE (expr)) == 'c') + expr = build1 (NOP_EXPR, TREE_TYPE (expr), expr); + + add_stmt (expr); +} + +/* Do the opposite and emit a statement as an expression. To begin, + create a new binding level and return it. */ tree c_begin_stmt_expr (void) @@ -6679,63 +6723,77 @@ c_begin_stmt_expr (void) tree c_finish_stmt_expr (tree body) { - tree ret, last, type; + tree last, type, tmp, val; tree *last_p; body = c_end_compound_stmt (body, true); - /* Locate the last statement in BODY. */ - last = body, last_p = &body; - if (TREE_CODE (last) == BIND_EXPR) - { - last_p = &BIND_EXPR_BODY (last); - last = BIND_EXPR_BODY (last); - } + /* Locate the last statement in BODY. See c_end_compound_stmt + about always returning a BIND_EXPR. */ + last_p = &BIND_EXPR_BODY (body); + last = BIND_EXPR_BODY (body); + + continue_searching: if (TREE_CODE (last) == STATEMENT_LIST) { - tree_stmt_iterator i = tsi_last (last); - if (tsi_end_p (i)) + tree_stmt_iterator i; + + /* This can happen with degenerate cases like ({ }). No value. */ + if (!TREE_SIDE_EFFECTS (last)) + return body; + + /* If we're supposed to generate side effects warnings, process + all of the statements except the last. */ + if (extra_warnings || warn_unused_value) { - type = void_type_node; - /* ??? Warn */ - goto no_expr; + for (i = tsi_start (last); !tsi_one_before_end_p (i); tsi_next (&i)) + emit_side_effect_warnings (tsi_stmt (i)); } else - { - last_p = tsi_stmt_ptr (i); - last = *last_p; - } + i = tsi_last (last); + last_p = tsi_stmt_ptr (i); + last = *last_p; } - /* If the last statement is an EXPR_STMT, then unwrap it. Otherwise - voidify_wrapper_expr will stuff it inside a MODIFY_EXPR and we'll - fail gimplification. */ - /* ??? Should we go ahead and perform voidify_wrapper_expr here? - We've got about all the information we need here. All we'd have - to do even for proper type safety is to create, in effect, - ( ({ ...; tmp = last; }), tmp ) - I.e. a COMPOUND_EXPR with the rhs being the compiler temporary. - Not going to try this now, since it's not clear what should - happen (wrt bindings) with new temporaries at this stage. It's - easier once we begin gimplification. */ - if (TREE_CODE (last) == EXPR_STMT) - *last_p = last = EXPR_STMT_EXPR (last); + /* If the end of the list is exception related, then the list was split + by a call to push_cleanup. Continue searching. */ + if (TREE_CODE (last) == TRY_FINALLY_EXPR + || TREE_CODE (last) == TRY_CATCH_EXPR) + { + last_p = &TREE_OPERAND (last, 0); + last = *last_p; + goto continue_searching; + } + + /* In the case that the BIND_EXPR is not necessary, return the + expression out from inside it. */ + if (last == BIND_EXPR_BODY (body) && BIND_EXPR_VARS (body) == NULL) + return last; /* Extract the type of said expression. */ type = TREE_TYPE (last); - if (!type) - type = void_type_node; - - no_expr: - /* If what's left is compound, make sure we've got a BIND_EXPR, and - that it has the proper type. */ - ret = body; - if (TREE_CODE (ret) == STATEMENT_LIST) - ret = build (BIND_EXPR, type, NULL, ret, NULL); - else if (TREE_CODE (ret) == BIND_EXPR) - TREE_TYPE (ret) = type; - return ret; + /* If we're not returning a value at all, then the BIND_EXPR that + we already have is a fine expression to return. */ + if (!type || VOID_TYPE_P (type)) + return body; + + /* Now that we've located the expression containing the value, it seems + silly to make voidify_wrapper_expr repeat the process. Create a + temporary of the appropriate type and stick it in a TARGET_EXPR. */ + tmp = create_tmp_var_raw (type, NULL); + + /* Unwrap a no-op NOP_EXPR as added by c_finish_expr_stmt. This avoids + tree_expr_nonnegative_p giving up immediately. */ + val = last; + if (TREE_CODE (val) == NOP_EXPR + && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0))) + val = TREE_OPERAND (val, 0); + + *last_p = build (MODIFY_EXPR, void_type_node, tmp, val); + SET_EXPR_LOCUS (*last_p, EXPR_LOCUS (last)); + + return build (TARGET_EXPR, type, tmp, body, NULL_TREE, NULL_TREE); } /* Begin and end compound statements. This is as simple as pushing @@ -6791,10 +6849,17 @@ c_end_compound_stmt (tree stmt, bool do_scope) void push_cleanup (tree decl ATTRIBUTE_UNUSED, tree cleanup, bool eh_only) { - enum tree_code code = eh_only ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR; - tree stmt = build_stmt (code, NULL, cleanup); + enum tree_code code; + tree stmt, list; + bool stmt_expr; + + code = eh_only ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR; + stmt = build_stmt (code, NULL, cleanup); add_stmt (stmt); - TREE_OPERAND (stmt, 0) = push_stmt_list (); + stmt_expr = STATEMENT_LIST_STMT_EXPR (cur_stmt_list); + list = push_stmt_list (); + TREE_OPERAND (stmt, 0) = list; + STATEMENT_LIST_STMT_EXPR (list) = stmt_expr; } /* Build a binary-operation expression without default conversions. @@ -7412,7 +7477,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, constant expression involving such literals or a conditional expression involving such literals) and it is non-negative. */ - if (c_tree_expr_nonnegative_p (sop)) + if (tree_expr_nonnegative_p (sop)) /* OK */; /* Do not warn if the comparison is an equality operation, the unsigned quantity is an integral constant, and it diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4ec0ee6d18c4..679289af8737 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2004-06-21 Richard Henderson + + * semantics.c (finish_expr_stmt): Call verify_sequence_points. + 2004-06-20 Richard Henderson * cp-tree.h (add_decl_stmt): Declare. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 92efe443a6d5..826ac688a761 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -493,7 +493,11 @@ finish_expr_stmt (tree expr) if (expr != NULL_TREE) { if (!processing_template_decl) - expr = convert_to_void (expr, "statement"); + { + if (warn_sequence_point) + verify_sequence_points (expr); + expr = convert_to_void (expr, "statement"); + } else if (!type_dependent_expression_p (expr)) convert_to_void (build_non_dependent_expr (expr), "statement"); diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 220d1af95ac1..517d5508b954 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -9267,6 +9267,37 @@ tree_expr_nonnegative_p (tree t) case RTL_EXPR: return rtl_expr_nonnegative_p (RTL_EXPR_RTL (t)); + case TARGET_EXPR: + { + tree temp = TARGET_EXPR_SLOT (t); + t = TARGET_EXPR_INITIAL (t); + + /* If the initializer is non-void, then it's a normal expression + that will be assigned to the slot. */ + if (!VOID_TYPE_P (t)) + return tree_expr_nonnegative_p (t); + + /* Otherwise, the initializer sets the slot in some way. One common + way is an assignment statement at the end of the initializer. */ + while (1) + { + if (TREE_CODE (t) == BIND_EXPR) + t = expr_last (BIND_EXPR_BODY (t)); + else if (TREE_CODE (t) == TRY_FINALLY_EXPR + || TREE_CODE (t) == TRY_CATCH_EXPR) + t = expr_last (TREE_OPERAND (t, 0)); + else if (TREE_CODE (t) == STATEMENT_LIST) + t = expr_last (t); + else + break; + } + if (TREE_CODE (t) == MODIFY_EXPR + && TREE_OPERAND (t, 0) == temp) + return tree_expr_nonnegative_p (TREE_OPERAND (t, 1)); + + return 0; + } + case CALL_EXPR: { tree fndecl = get_callee_fndecl (t); diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 92c52a9365b9..f6e4a04bf9bf 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -2472,13 +2472,19 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value) return ret; /* If we are initializing something from a TARGET_EXPR, strip the - TARGET_EXPR and initialize it directly. */ + TARGET_EXPR and initialize it directly, if possible. This can't + be done if the initializer is void, since that implies that the + temporary is set in some non-trivial way. */ /* What about code that pulls out the temp and uses it elsewhere? I think that such code never uses the TARGET_EXPR as an initializer. If I'm wrong, we'll abort because the temp won't have any RTL. In that case, I guess we'll need to replace references somehow. */ if (TREE_CODE (*from_p) == TARGET_EXPR) - *from_p = TARGET_EXPR_INITIAL (*from_p); + { + tree init = TARGET_EXPR_INITIAL (*from_p); + if (!VOID_TYPE_P (TREE_TYPE (init))) + *from_p = init; + } /* If we're assigning from a ?: expression with ADDRESSABLE type, push the assignment down into the branches, since we can't generate a @@ -3021,22 +3027,29 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p) if (init) { - /* TARGET_EXPR temps aren't part of the enclosing block, so add it to the - temps list. */ + /* TARGET_EXPR temps aren't part of the enclosing block, so add it + to the temps list. */ gimple_add_tmp_var (temp); - /* Build up the initialization and add it to pre_p. Special handling - for BIND_EXPR can result in fewer temporaries created. */ - if (TREE_CODE (init) == BIND_EXPR) - gimplify_bind_expr (&init, temp, pre_p); - if (init != temp) + /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the + expression is supposed to initialize the slot. */ + if (VOID_TYPE_P (TREE_TYPE (init))) + ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); + else { - if (! VOID_TYPE_P (TREE_TYPE (init))) - init = build (MODIFY_EXPR, void_type_node, temp, init); - ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); - if (ret == GS_ERROR) - return GS_ERROR; + /* Special handling for BIND_EXPR can result in fewer temps. */ + ret = GS_OK; + if (TREE_CODE (init) == BIND_EXPR) + gimplify_bind_expr (&init, temp, pre_p); + if (init != temp) + { + init = build (MODIFY_EXPR, void_type_node, temp, init); + ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, + fb_none); + } } + if (ret == GS_ERROR) + return GS_ERROR; append_to_statement_list (init, pre_p); /* If needed, push the cleanup for the temp. */ diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 8176bd97d2a0..4414309ca7d5 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -1918,7 +1918,7 @@ build_module_descriptor (void) build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0)); decelerator = build_function_call (execclass_decl, parms); - c_expand_expr_stmt (decelerator); + add_stmt (decelerator); add_stmt (c_end_compound_stmt (compound, true)); finish_function (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index de97d53f6b82..d9f579e2968d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-06-21 Richard Henderson + + * gcc.dg/tree-ssa/20030714-1.c: Rename variables to avoid + merging && to BIT_FIELD_REF. + 2004-06-21 Richard Sandiford * g++.dg/opt/placeholder1.C: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c index 63823f71059e..1caa22ab5358 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c @@ -19,12 +19,12 @@ find_base_value (src) rtx src; { rtx temp; - rtx src_0; - rtx src_1; + rtx src_0, src_2; + rtx src_1, src_3; - if ((src_0->code == REG) && (({src_0;})->frame_related)) + if ((src_0->code == REG) && (({src_2;})->frame_related)) return find_base_value (src_0); - if ((src_1->code == REG) && (({ src_1;})->frame_related)) + if ((src_1->code == REG) && (({ src_3;})->frame_related)) return find_base_value (src_1); if (src_0->code == REG) find_base_value (src_0); @@ -41,4 +41,3 @@ find_base_value (src) /* There should be three loads of ->code. */ /* { dg-final { scan-tree-dump-times "->code" 3 "dom3"} } */ - diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index d5ceac6d6c6f..24bf3d1b2ff3 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1251,11 +1251,14 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data) case STRING_CST: *walk_subtrees = 0; return NULL; + /* Recognize assignments of large structures and constructors of big arrays. */ case INIT_EXPR: - case TARGET_EXPR: case MODIFY_EXPR: + x = TREE_OPERAND (x, 0); + /* FALLTHRU */ + case TARGET_EXPR: case CONSTRUCTOR: { HOST_WIDE_INT size; -- 2.43.5