From 350fae6628af14c2e760694d39baec5f7858057c Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Sat, 26 Jun 2004 21:11:23 +0000 Subject: [PATCH] c-common.c (c_safe_from_p, [...]): Deleted. 2004-06-26 Richard Kenner * c-common.c (c_safe_from_p, c_walk_subtrees): Deleted. * c-common.def (DECL_STMT): Remove. * c-common.h (DECL_STMT_DECL): Deleted. (COMPOUNT_LITERAL_EXPR_DECL): Use DECL_EXPR_DECL. (c_safe_from_p, c_walk_subtrees): Deleted. * c-decl.c, c-parse.in, c-pretty-print.c: DECL_STMT now DECL_EXPR. * c-dump.c (c_dump_tree, case DECL_STMT): Deleted. * c-gimplify.c (gimplify_decl_stmt): Deleted. (gimplify_compound_literal_expr): Use DECL_EXPR_DECL and gimplify_and_add. (c_gimplify_expr, case DECL_EXPR): New case. (c_gimplify_expr, case DECL_STMT): Deleted. * c-lang.c (LANG_HOOKS_SAFE_FROM_P): Likewise. (LANG_HOOKS_TREE_INLINING_WALK_SUBTREES): Likewise. * expr.c (safe_from_p, case 's'): New case. * gimplify.c (gimplify_decl_expr): New function. (gimplify_expr, case DECL_EXPR): New case. * tree-inline.c (walk_tree): Walk into all fields of a type and decl only if they are in a DECL_EXPR. (mark_local_for_remap_r): Minor code cleanup. * tree-outof-ssa.c (discover_nonconstant_array_refs_r): Add else. * tree.c (has_cleanups, case DECL_EXPR): New case. * tree.def (DECL_EXPR): New code. * tree.h (DECL_EXPR_DECL): New macro. * objc/objc-lang.c (LANG_HOOKS_SAFE_FROM_P): Deleted. From-SVN: r83721 --- gcc/c-common.c | 69 ------------- gcc/c-common.def | 4 - gcc/c-common.h | 12 +-- gcc/c-decl.c | 8 +- gcc/c-dump.c | 5 - gcc/c-gimplify.c | 96 +++-------------- gcc/c-lang.c | 5 - gcc/c-parse.in | 6 +- gcc/c-pretty-print.c | 12 ++- gcc/cp/ChangeLog | 8 ++ gcc/cp/call.c | 2 +- gcc/cp/cp-lang.c | 2 - gcc/cp/cp-tree.h | 2 +- gcc/cp/cxx-pretty-print.c | 2 +- gcc/cp/decl.c | 14 +-- gcc/cp/decl2.c | 2 +- gcc/cp/init.c | 2 +- gcc/cp/name-lookup.c | 2 +- gcc/cp/parser.c | 2 +- gcc/cp/pt.c | 8 +- gcc/cp/semantics.c | 16 +-- gcc/cp/tree.c | 19 ++-- gcc/expr.c | 8 ++ gcc/gimplify.c | 72 ++++++++++++- gcc/objc/objc-lang.c | 2 - gcc/tree-inline.c | 211 +++++++++++++++++++------------------- gcc/tree-outof-ssa.c | 2 +- gcc/tree.c | 4 + gcc/tree.def | 3 + gcc/tree.h | 4 + 30 files changed, 270 insertions(+), 334 deletions(-) diff --git a/gcc/c-common.c b/gcc/c-common.c index 0edbd5f7925..f48ac09fbdd 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -3718,28 +3718,6 @@ c_expand_expr (tree exp, rtx target, enum machine_mode tmode, } } -/* Hook used by safe_from_p to handle language-specific tree codes. */ - -int -c_safe_from_p (rtx target, tree exp) -{ - /* We can see statements here when processing the body of a - statement-expression. For a declaration statement declaring a - variable, look at the variable's initializer. */ - if (TREE_CODE (exp) == DECL_STMT) - { - tree decl = DECL_STMT_DECL (exp); - - if (TREE_CODE (decl) == VAR_DECL - && DECL_INITIAL (decl) - && !safe_from_p (target, DECL_INITIAL (decl), /*top_p=*/0)) - return 0; - } - - /* Assume everything else is safe. */ - return 1; -} - /* Hook used by unsafe_for_reeval to handle language-specific tree codes. */ int @@ -5125,53 +5103,6 @@ check_function_arguments_recurse (void (*callback) (*callback) (ctx, param, param_num); } -/* C implementation of lang_hooks.tree_inlining.walk_subtrees. Tracks the - locus from EXPR_LOCUS and handles DECL_STMT specially. */ - -tree -c_walk_subtrees (tree *tp, int *walk_subtrees_p ATTRIBUTE_UNUSED, - walk_tree_fn func, void *data, void *htab) -{ - enum tree_code code = TREE_CODE (*tp); - location_t save_locus; - tree result; - -#define WALK_SUBTREE(NODE) \ - do \ - { \ - result = walk_tree (&(NODE), func, data, htab); \ - if (result) goto out; \ - } \ - while (0) - - if (code != DECL_STMT) - return NULL_TREE; - - /* Set input_location here so we get the right instantiation context - if we call instantiate_decl from inlinable_function_p. */ - save_locus = input_location; - if (EXPR_LOCUS (*tp)) - input_location = *EXPR_LOCUS (*tp); - - /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk - into declarations that are just mentioned, rather than - declared; they don't really belong to this part of the tree. - And, we can see cycles: the initializer for a declaration can - refer to the declaration itself. */ - WALK_SUBTREE (DECL_INITIAL (DECL_STMT_DECL (*tp))); - WALK_SUBTREE (DECL_SIZE (DECL_STMT_DECL (*tp))); - WALK_SUBTREE (DECL_SIZE_UNIT (DECL_STMT_DECL (*tp))); - WALK_SUBTREE (TREE_CHAIN (*tp)); - *walk_subtrees_p = 0; - - /* We didn't find what we were looking for. */ - out: - input_location = save_locus; - return result; - -#undef WALK_SUBTREE -} - /* Function to help qsort sort FIELD_DECLs by name order. */ int diff --git a/gcc/c-common.def b/gcc/c-common.def index 5d8c237831d..fa45ad0526a 100644 --- a/gcc/c-common.def +++ b/gcc/c-common.def @@ -33,10 +33,6 @@ DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", '1', 1) obtain the expression. */ DEFTREECODE (EXPR_STMT, "expr_stmt", 'e', 1) -/* Used to represent a local declaration. The operand is - DECL_STMT_DECL. */ -DEFTREECODE (DECL_STMT, "decl_stmt", 'e', 1) - /* Used to represent a `for' statement. The operands are FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */ DEFTREECODE (FOR_STMT, "for_stmt", 'e', 4) diff --git a/gcc/c-common.h b/gcc/c-common.h index ae5fbb690bc..454d4899237 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -733,10 +733,6 @@ extern void finish_file (void); #define SWITCH_TYPE(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 2) -/* DECL_STMT accessor. This gives access to the DECL associated with - the given declaration statement. */ -#define DECL_STMT_DECL(NODE) TREE_OPERAND (DECL_STMT_CHECK (NODE), 0) - /* STMT_EXPR accessor. */ #define STMT_EXPR_STMT(NODE) TREE_OPERAND (STMT_EXPR_CHECK (NODE), 0) @@ -748,7 +744,7 @@ extern void finish_file (void); #define COMPOUND_LITERAL_EXPR_DECL_STMT(NODE) \ TREE_OPERAND (COMPOUND_LITERAL_EXPR_CHECK (NODE), 0) #define COMPOUND_LITERAL_EXPR_DECL(NODE) \ - DECL_STMT_DECL (COMPOUND_LITERAL_EXPR_DECL_STMT (NODE)) + DECL_EXPR_DECL (COMPOUND_LITERAL_EXPR_DECL_STMT (NODE)) #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM, @@ -761,7 +757,7 @@ enum c_tree_code { #undef DEFTREECODE #define c_common_stmt_codes \ - EXPR_STMT, DECL_STMT, FOR_STMT, \ + EXPR_STMT, FOR_STMT, \ WHILE_STMT, DO_STMT, \ BREAK_STMT, CONTINUE_STMT, SWITCH_STMT @@ -844,8 +840,6 @@ extern int vector_types_convertible_p (tree t1, tree t2); extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *); -extern int c_safe_from_p (rtx, tree); - extern int c_staticp (tree); extern int c_common_unsafe_for_reeval (tree); @@ -872,8 +866,6 @@ extern void dump_time_statistics (void); extern bool c_dump_tree (void *, tree); -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); diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 7aeba0896c2..4591ec95d7a 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -2943,7 +2943,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) } if (TREE_CODE (decl) != FUNCTION_DECL) - add_stmt (build_stmt (DECL_STMT, decl)); + add_stmt (build_stmt (DECL_EXPR, decl)); } if (!DECL_FILE_SCOPE_P (decl)) @@ -2970,7 +2970,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree) { if (!DECL_FILE_SCOPE_P (decl) && variably_modified_type_p (TREE_TYPE (decl))) - add_stmt (build_stmt (DECL_STMT, decl)); + add_stmt (build_stmt (DECL_EXPR, decl)); rest_of_decl_compilation (decl, NULL, DECL_FILE_SCOPE_P (decl), 0); } @@ -3072,7 +3072,7 @@ build_compound_literal (tree type, tree init) { /* We do not use start_decl here because we have a type, not a declarator; and do not use finish_decl because the decl should be stored inside - the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_STMT. */ + the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_EXPR. */ tree decl = build_decl (VAR_DECL, NULL_TREE, type); tree complit; tree stmt; @@ -3096,7 +3096,7 @@ build_compound_literal (tree type, tree init) if (type == error_mark_node || !COMPLETE_TYPE_P (type)) return error_mark_node; - stmt = build_stmt (DECL_STMT, decl); + stmt = build_stmt (DECL_EXPR, decl); complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt); TREE_SIDE_EFFECTS (complit) = 1; diff --git a/gcc/c-dump.c b/gcc/c-dump.c index 91acac844c7..73b973e235a 100644 --- a/gcc/c-dump.c +++ b/gcc/c-dump.c @@ -60,11 +60,6 @@ c_dump_tree (void *dump_info, tree t) dump_stmt (di, t); break; - case DECL_STMT: - dump_stmt (di, t); - dump_child ("decl", DECL_STMT_DECL (t)); - break; - case DO_STMT: dump_stmt (di, t); dump_child ("body", DO_BODY (t)); diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c index 811365e2746..d899ba3593c 100644 --- a/gcc/c-gimplify.c +++ b/gcc/c-gimplify.c @@ -465,90 +465,17 @@ gimplify_switch_stmt (tree *stmt_p) return GS_ALL_DONE; } -/* Gimplifies a DECL_STMT node *STMT_P by making any necessary allocation - and initialization explicit. */ - -static enum gimplify_status -gimplify_decl_stmt (tree *stmt_p) -{ - tree stmt = *stmt_p; - tree decl = DECL_STMT_DECL (stmt); - - *stmt_p = NULL_TREE; - - if (TREE_TYPE (decl) == error_mark_node) - return GS_ERROR; - - if (TREE_CODE (decl) == TYPE_DECL) - gimplify_type_sizes (TREE_TYPE (decl), stmt_p); - - else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) - { - tree init = DECL_INITIAL (decl); - - if (!TREE_CONSTANT (DECL_SIZE (decl))) - { - /* This is a variable-sized decl. Simplify its size and mark it - for deferred expansion. Note that mudflap depends on the format - of the emitted code: see mx_register_decls(). */ - - tree t, args; - - gimplify_type_sizes (TREE_TYPE (decl), stmt_p); - gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p); - gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p); - - args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL); - t = build_fold_addr_expr (decl); - args = tree_cons (NULL, t, args); - t = implicit_built_in_decls[BUILT_IN_STACK_ALLOC]; - t = build_function_call_expr (t, args); - - gimplify_and_add (t, stmt_p); - DECL_DEFER_OUTPUT (decl) = 1; - } - - if (init && init != error_mark_node) - { - if (!TREE_STATIC (decl)) - { - /* Do not warn about int x = x; as it is a GCC extension - to turn off this warning but only if warn_init_self - is zero. */ - if (init == decl && !warn_init_self) - TREE_NO_WARNING (decl) = 1; - - DECL_INITIAL (decl) = NULL_TREE; - init = build (MODIFY_EXPR, void_type_node, decl, init); - gimplify_and_add (init, stmt_p); - } - else - /* We must still examine initializers for static variables - as they may contain a label address. */ - walk_tree (&init, force_labels_r, NULL, NULL); - } - - /* This decl isn't mentioned in the enclosing block, so add it to the - list of temps. FIXME it seems a bit of a kludge to say that - anonymous artificial vars aren't pushed, but everything else is. */ - if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE) - gimple_add_tmp_var (decl); - } - - return GS_ALL_DONE; -} - /* Gimplification of expression trees. */ /* Gimplify a C99 compound literal expression. This just means adding the - DECL_STMT before the current EXPR_STMT and using its anonymous decl + DECL_EXPR before the current EXPR_STMT and using its anonymous decl instead. */ static enum gimplify_status gimplify_compound_literal_expr (tree *expr_p, tree *pre_p) { tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p); - tree decl = DECL_STMT_DECL (decl_s); + tree decl = DECL_EXPR_DECL (decl_s); /* This decl isn't mentioned in the enclosing block, so add it to the list of temps. FIXME it seems a bit of a kludge to say that @@ -556,8 +483,7 @@ gimplify_compound_literal_expr (tree *expr_p, tree *pre_p) if (DECL_NAME (decl) == NULL_TREE) gimple_add_tmp_var (decl); - gimplify_decl_stmt (&decl_s); - append_to_statement_list (decl_s, pre_p); + gimplify_and_add (decl_s, pre_p); *expr_p = decl; return GS_OK; } @@ -571,6 +497,19 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED) switch (code) { + case DECL_EXPR: + /* This is handled mostly by gimplify.c, but we have to deal with + not warning about int x = x; as it is a GCC extension to turn off + this warning but only if warn_init_self is zero. */ + if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL + && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p)) + && !TREE_STATIC (DECL_EXPR_DECL (*expr_p)) + && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p)) + == DECL_EXPR_DECL (*expr_p)) + && !warn_init_self) + TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1; + return GS_UNHANDLED; + case COMPOUND_LITERAL_EXPR: return gimplify_compound_literal_expr (expr_p, pre_p); @@ -589,9 +528,6 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED) case EXPR_STMT: return gimplify_expr_stmt (expr_p); - case DECL_STMT: - return gimplify_decl_stmt (expr_p); - case CONTINUE_STMT: *expr_p = build_bc_goto (bc_continue); return GS_ALL_DONE; diff --git a/gcc/c-lang.c b/gcc/c-lang.c index 74b04ebc17a..03b05b26efa 100644 --- a/gcc/c-lang.c +++ b/gcc/c-lang.c @@ -60,8 +60,6 @@ enum c_language_kind c_language = clk_c; #define LANG_HOOKS_POST_OPTIONS c_common_post_options #undef LANG_HOOKS_GET_ALIAS_SET #define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set -#undef LANG_HOOKS_SAFE_FROM_P -#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p #undef LANG_HOOKS_EXPAND_EXPR #define LANG_HOOKS_EXPAND_EXPR c_expand_expr #undef LANG_HOOKS_EXPAND_DECL @@ -103,9 +101,6 @@ enum c_language_kind c_language = clk_c; #undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE #define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE c_common_format_attribute_table -#undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES -#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \ - c_walk_subtrees #undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN #define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \ c_cannot_inline_tree_fn diff --git a/gcc/c-parse.in b/gcc/c-parse.in index a96241a3e5c..96468279245 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -1537,7 +1537,7 @@ nested_function: add_stmt ($6); finish_function (); pop_function_context (); - add_stmt (build_stmt (DECL_STMT, decl)); } + add_stmt (build_stmt (DECL_EXPR, decl)); } ; notype_nested_function: @@ -1567,7 +1567,7 @@ notype_nested_function: add_stmt ($6); finish_function (); pop_function_context (); - add_stmt (build_stmt (DECL_STMT, decl)); } + add_stmt (build_stmt (DECL_EXPR, decl)); } ; /* Any kind of declarator (thus, all declarators allowed @@ -2016,7 +2016,7 @@ label_decl: { tree label = declare_label (TREE_VALUE (link)); C_DECLARED_LABEL_FLAG (label) = 1; - add_stmt (build_stmt (DECL_STMT, label)); + add_stmt (build_stmt (DECL_EXPR, label)); } } ; diff --git a/gcc/c-pretty-print.c b/gcc/c-pretty-print.c index 4d0b06d5de9..fd3ef82ac02 100644 --- a/gcc/c-pretty-print.c +++ b/gcc/c-pretty-print.c @@ -261,6 +261,13 @@ pp_c_pointer (c_pretty_printer *pp, tree t) pp_c_type_qualifier_list (pp, t); break; + /* ??? This node is now in GENERIC and so shouldn't be here. But + we'll fix that later. */ + case DECL_EXPR: + pp_declaration (pp, DECL_EXPR_DECL (t)); + pp_needs_newline (pp) = true; + break; + default: pp_unsupported_tree (pp, t); } @@ -1982,11 +1989,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt) pp_needs_newline (pp) = true; break; - case DECL_STMT: - pp_declaration (pp, DECL_STMT_DECL (stmt)); - pp_needs_newline (pp) = true; - break; - default: dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true); break; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f5d903cdb6f..6812f8b86a3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2004-06-26 Richard Kenner + + * call.c, cp-tree.h, cxx-pretty-print.c, decl.c, decl2.c: + Rename DECL_STMT to DECL_EXPR. + * init.c, name-lookup.c, parser.c, pt.c, semantics.c: Likewise. + * cp-lang.c (LANG_HOOKS_SAFE_FROM_P): Deleted. + * tree.c (cp_walk_subtrees): Don't call c_walk_subtrees. + 2004-06-26 Jan Hubicka PR C++/14865 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index e02fa17e403..5cbf808d8ec 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6468,7 +6468,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup) init = build (INIT_EXPR, type, var, expr); if (at_function_scope_p ()) { - add_decl_stmt (var); + add_decl_expr (var); *cleanup = cxx_maybe_build_cleanup (var); /* We must be careful to destroy the temporary only diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index 5af5b97333d..98b94581793 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -72,8 +72,6 @@ static void cxx_initialize_diagnostics (diagnostic_context *); #define LANG_HOOKS_EXPAND_EXPR cxx_expand_expr #undef LANG_HOOKS_EXPAND_DECL #define LANG_HOOKS_EXPAND_DECL c_expand_decl -#undef LANG_HOOKS_SAFE_FROM_P -#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p #undef LANG_HOOKS_PARSE_FILE #define LANG_HOOKS_PARSE_FILE c_common_parse_file #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 143c931aa3a..f2ebb649988 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4147,7 +4147,7 @@ extern void pop_to_parent_deferring_access_checks (void); extern void perform_deferred_access_checks (void); extern void perform_or_defer_access_check (tree, tree); extern void init_cp_semantics (void); -extern void add_decl_stmt (tree); +extern void add_decl_expr (tree); extern tree finish_expr_stmt (tree); extern tree begin_if_stmt (void); extern void finish_if_stmt_cond (tree, tree); diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index cd086117634..c1337a925ea 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -1446,7 +1446,7 @@ pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t) static void pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t) { - t = DECL_STMT_DECL (t); + t = DECL_EXPR_DECL (t); pp_cxx_type_specifier_seq (pp, t); if (TYPE_P (t)) pp_cxx_abstract_declarator (pp, t); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5f7fb81ee06..9d2aedb8123 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3873,8 +3873,8 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup) /* Convert INIT to the reference type TYPE. This may involve the creation of a temporary, whose lifetime must be the same as that - of the reference. If so, a DECL_STMT for the temporary will be - added just after the DECL_STMT for DECL. That's why we don't set + of the reference. If so, a DECL_EXPR for the temporary will be + added just after the DECL_EXPR for DECL. That's why we don't set DECL_INITIAL for local references (instead assigning to them explicitly); we need to allow the temporary to be initialized first. */ @@ -4527,7 +4527,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec) return; /* We defer emission of local statics until the corresponding - DECL_STMT is expanded. */ + DECL_EXPR is expanded. */ defer_p = DECL_FUNCTION_SCOPE_P (decl) || DECL_VIRTUAL_P (decl); /* We try to defer namespace-scope static constants so that they are @@ -4702,7 +4702,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) { /* Add this declaration to the statement-tree. */ if (at_function_scope_p ()) - add_decl_stmt (decl); + add_decl_expr (decl); if (init && DECL_INITIAL (decl)) DECL_INITIAL (decl) = init; @@ -4808,10 +4808,10 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) } /* Add this declaration to the statement-tree. This needs to happen - after the call to check_initializer so that the DECL_STMT for a - reference temp is added before the DECL_STMT for the reference itself. */ + after the call to check_initializer so that the DECL_EXPR for a + reference temp is added before the DECL_EXPR for the reference itself. */ if (at_function_scope_p ()) - add_decl_stmt (decl); + add_decl_expr (decl); if (TREE_CODE (decl) == VAR_DECL) layout_var_decl (decl); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index ae310768b75..142bd4b7f87 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1227,7 +1227,7 @@ finish_anon_union (tree anon_union_decl) pushdecl (anon_union_decl); if (building_stmt_tree () && at_function_scope_p ()) - add_decl_stmt (anon_union_decl); + add_decl_expr (anon_union_decl); else if (!processing_template_decl) rest_of_decl_compilation (anon_union_decl, NULL, toplevel_bindings_p (), at_eof); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index ceb6c4bc32e..425a853186d 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2360,7 +2360,7 @@ get_temp_regvar (tree type, tree init) tree decl; decl = create_temporary_var (type); - add_decl_stmt (decl); + add_decl_expr (decl); finish_expr_stmt (build_modify_expr (decl, INIT_EXPR, init)); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 1b755c92320..b650d7443d1 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -2269,7 +2269,7 @@ do_local_using_decl (tree decl, tree scope, tree name) if (building_stmt_tree () && at_function_scope_p ()) - add_decl_stmt (decl); + add_decl_expr (decl); oldval = lookup_name_current_level (name); oldtype = lookup_type_current_level (name); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 346ad1cabcf..e6b1f920815 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10695,7 +10695,7 @@ cp_parser_init_declarator (cp_parser* parser, /* Leave the SCOPE, now that we have processed the initializer. It is important to do this before calling cp_finish_decl because it - makes decisions about whether to create DECL_STMTs or not based + makes decisions about whether to create DECL_EXPRs or not based on the current scope. */ if (pop_p) pop_scope (scope); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a0f140f13d0..a1142f3b358 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4587,7 +4587,7 @@ struct pair_fn_data /* Called from for_each_template_parm via walk_tree. */ static tree -for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d) +for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) { tree t = *tp; struct pair_fn_data *pfd = (struct pair_fn_data *) d; @@ -7764,12 +7764,12 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) args, complain, in_decl)); break; - case DECL_STMT: + case DECL_EXPR: { tree decl; tree init; - decl = DECL_STMT_DECL (t); + decl = DECL_EXPR_DECL (t); if (TREE_CODE (decl) == LABEL_DECL) finish_label_decl (DECL_NAME (decl)); else if (TREE_CODE (decl) == USING_DECL) @@ -7825,7 +7825,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) } } - /* A DECL_STMT can also be used as an expression, in the condition + /* A DECL_EXPR can also be used as an expression, in the condition clause of an if/for/while construct. */ return decl; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c9f66d9dc1c..b4894607201 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -316,9 +316,9 @@ maybe_cleanup_point_expr (tree expr) /* Create a declaration statement for the declaration given by the DECL. */ void -add_decl_stmt (tree decl) +add_decl_expr (tree decl) { - tree r = build_stmt (DECL_STMT, decl); + tree r = build_stmt (DECL_EXPR, decl); if (DECL_INITIAL (decl)) r = maybe_cleanup_point_expr (r); add_stmt (r); @@ -382,7 +382,7 @@ push_cleanup (tree decl, tree cleanup, bool eh_only) /* Begin a conditional that might contain a declaration. When generating normal code, we want the declaration to appear before the statement containing the conditional. When generating template code, we want the - conditional to be rendered as the raw DECL_STMT. */ + conditional to be rendered as the raw DECL_EXPR. */ static void begin_cond (tree *cond_p) @@ -399,7 +399,7 @@ finish_cond (tree *cond_p, tree expr) if (processing_template_decl) { tree cond = pop_stmt_list (*cond_p); - if (TREE_CODE (cond) == DECL_STMT) + if (TREE_CODE (cond) == DECL_EXPR) expr = cond; } *cond_p = expr; @@ -1141,7 +1141,7 @@ void finish_label_decl (tree name) { tree decl = declare_local_label (name); - add_decl_stmt (decl); + add_decl_expr (decl); } /* When DECL goes out of scope, make sure that CLEANUP is executed. */ @@ -2950,10 +2950,10 @@ finalize_nrv_r (tree* tp, int* walk_subtrees, void* data) else if (TREE_CODE (*tp) == CLEANUP_STMT && CLEANUP_DECL (*tp) == dp->var) CLEANUP_EH_ONLY (*tp) = 1; - /* Replace the DECL_STMT for the NRV with an initialization of the + /* Replace the DECL_EXPR for the NRV with an initialization of the RESULT_DECL, if needed. */ - else if (TREE_CODE (*tp) == DECL_STMT - && DECL_STMT_DECL (*tp) == dp->var) + else if (TREE_CODE (*tp) == DECL_EXPR + && DECL_EXPR_DECL (*tp) == dp->var) { tree init; if (DECL_INITIAL (dp->var) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 527e9c27d50..4ae07798dee 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1962,14 +1962,11 @@ cp_build_type_attribute_variant (tree type, tree attributes) } /* Apply FUNC to all language-specific sub-trees of TP in a pre-order - traversal. Called from walk_tree(). */ + traversal. Called from walk_tree. */ tree -cp_walk_subtrees (tree* tp, - int* walk_subtrees_p, - walk_tree_fn func, - void* data, - void* htab) +cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func, + void *data, void *htab) { enum tree_code code = TREE_CODE (*tp); location_t save_locus; @@ -2030,7 +2027,7 @@ cp_walk_subtrees (tree* tp, default: input_location = save_locus; - return c_walk_subtrees (tp, walk_subtrees_p, func, data, htab); + return NULL_TREE; } /* We didn't find what we were looking for. */ @@ -2201,7 +2198,7 @@ init_tree (void) list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL); } -/* Called via walk_tree. If *TP points to a DECL_STMT for a local +/* Called via walk_tree. If *TP points to a DECL_EXPR for a local declaration, copies the declaration and enters it in the splay_tree pointed to by DATA (which is really a `splay_tree *'). */ @@ -2215,9 +2212,9 @@ mark_local_for_remap_r (tree* tp, tree decl; - if (TREE_CODE (t) == DECL_STMT - && nonstatic_local_decl_p (DECL_STMT_DECL (t))) - decl = DECL_STMT_DECL (t); + if (TREE_CODE (t) == DECL_EXPR + && nonstatic_local_decl_p (DECL_EXPR_DECL (t))) + decl = DECL_EXPR_DECL (t); else if (TREE_CODE (t) == LABEL_EXPR) decl = LABEL_EXPR_LABEL (t); else if (TREE_CODE (t) == TARGET_EXPR diff --git a/gcc/expr.c b/gcc/expr.c index 259eac1c989..a92eab6f9d9 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -6002,6 +6002,14 @@ safe_from_p (rtx x, tree exp, int top_p) else return 0; + case 's': + /* The only case we look at here is the DECL_INITIAL inside a + DECL_EXPR. */ + return (TREE_CODE (exp) != DECL_EXPR + || TREE_CODE (DECL_EXPR_DECL (exp)) != VAR_DECL + || !DECL_INITIAL (DECL_EXPR_DECL (exp)) + || safe_from_p (x, DECL_INITIAL (DECL_EXPR_DECL (exp)), 0)); + case '2': case '<': if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0)) diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 347e946e265..7ef88b565b3 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -660,7 +660,7 @@ copy_if_shared_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, /* Special-case BIND_EXPR. We should never be copying these, therefore we can omit examining BIND_EXPR_VARS. Which also avoids problems with double processing of the DECL_INITIAL, which could be seen via both - the BIND_EXPR_VARS and a DECL_STMT. */ + the BIND_EXPR_VARS and a DECL_EXPR. */ else if (code == BIND_EXPR) { if (TREE_VISITED (t)) @@ -1004,6 +1004,72 @@ gimplify_return_expr (tree stmt, tree *pre_p) return GS_ALL_DONE; } +/* Gimplifies a DECL_EXPR node *STMT_P by making any necessary allocation + and initialization explicit. */ + +static enum gimplify_status +gimplify_decl_expr (tree *stmt_p) +{ + tree stmt = *stmt_p; + tree decl = DECL_EXPR_DECL (stmt); + + *stmt_p = NULL_TREE; + + if (TREE_TYPE (decl) == error_mark_node) + return GS_ERROR; + + else if (TREE_CODE (decl) == TYPE_DECL) + gimplify_type_sizes (TREE_TYPE (decl), stmt_p); + + else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) + { + tree init = DECL_INITIAL (decl); + + if (!TREE_CONSTANT (DECL_SIZE (decl))) + { + /* This is a variable-sized decl. Simplify its size and mark it + for deferred expansion. Note that mudflap depends on the format + of the emitted code: see mx_register_decls(). */ + tree t, args; + + gimplify_type_sizes (TREE_TYPE (decl), stmt_p); + gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p); + gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p); + + args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL); + t = build_fold_addr_expr (decl); + args = tree_cons (NULL, t, args); + t = implicit_built_in_decls[BUILT_IN_STACK_ALLOC]; + t = build_function_call_expr (t, args); + + gimplify_and_add (t, stmt_p); + DECL_DEFER_OUTPUT (decl) = 1; + } + + if (init && init != error_mark_node) + { + if (!TREE_STATIC (decl)) + { + DECL_INITIAL (decl) = NULL_TREE; + init = build (MODIFY_EXPR, void_type_node, decl, init); + gimplify_and_add (init, stmt_p); + } + else + /* We must still examine initializers for static variables + as they may contain a label address. */ + walk_tree (&init, force_labels_r, NULL, NULL); + } + + /* This decl isn't mentioned in the enclosing block, so add it to the + list of temps. FIXME it seems a bit of a kludge to say that + anonymous artificial vars aren't pushed, but everything else is. */ + if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE) + gimple_add_tmp_var (decl); + } + + return GS_ALL_DONE; +} + /* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body and replacing the LOOP_EXPR with goto, but if the loop contains an EXIT_EXPR, we need to append a label for it to jump to. */ @@ -3521,6 +3587,10 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, *expr_p = DECL_INITIAL (*expr_p); break; + case DECL_EXPR: + ret = gimplify_decl_expr (expr_p); + break; + case EXC_PTR_EXPR: /* FIXME make this a decl. */ ret = GS_ALL_DONE; diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c index f786369521c..aa0f388e843 100644 --- a/gcc/objc/objc-lang.c +++ b/gcc/objc/objc-lang.c @@ -53,8 +53,6 @@ enum c_language_kind c_language = clk_objc; #define LANG_HOOKS_POST_OPTIONS c_common_post_options #undef LANG_HOOKS_GET_ALIAS_SET #define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set -#undef LANG_HOOKS_SAFE_FROM_P -#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p #undef LANG_HOOKS_PARSE_FILE #define LANG_HOOKS_PARSE_FILE c_common_parse_file #undef LANG_HOOKS_CLEAR_BINDING_STACK diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index e9bb3001555..ac5256220bc 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -2032,10 +2032,63 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_) if (result || ! walk_subtrees) return result; - if (code != EXIT_BLOCK_EXPR - && code != SAVE_EXPR - && code != BIND_EXPR - && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))) + /* If this is a DECL_EXPR, walk into various fields of the type or variable + that it's defining. We only want to walk into these fields of a decl + or type in this case. + + ??? Precisely which fields of types that we are supposed to walk in + this case vs. the normal case aren't well defined. */ + if (code == DECL_EXPR + && TREE_CODE (DECL_EXPR_DECL (*tp)) != ERROR_MARK + && TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK) + { + tree decl = DECL_EXPR_DECL (*tp); + tree type = TREE_TYPE (decl); + + /* Walk into fields of the DECL if it's not a type, then into fields + of the type in both cases. */ + + if (TREE_CODE (decl) != TYPE_DECL + && TREE_CODE (decl) != FIELD_DECL && TREE_CODE (decl) != PARM_DECL) + { + WALK_SUBTREE (DECL_INITIAL (decl)); + WALK_SUBTREE (DECL_SIZE (decl)); + WALK_SUBTREE (DECL_SIZE_UNIT (decl)); + } + + /* First do the common fields via recursion, then the fields we only + do when we are declaring the type or object. */ + WALK_SUBTREE (type); + WALK_SUBTREE (TYPE_SIZE (type)); + WALK_SUBTREE (TYPE_SIZE_UNIT (type)); + + /* If this is a record type, also walk the fields. */ + if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE + || TREE_CODE (type) == QUAL_UNION_TYPE) + { + tree field; + + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + { + /* We'd like to look at the type of the field, but we can easily + get infinite recursion. So assume it's pointed to elsewhere + in the tree. Also, ignore things that aren't fields. */ + if (TREE_CODE (field) != FIELD_DECL) + continue; + + WALK_SUBTREE (DECL_FIELD_OFFSET (field)); + WALK_SUBTREE (DECL_SIZE (field)); + WALK_SUBTREE (DECL_SIZE_UNIT (field)); + if (TREE_CODE (type) == QUAL_UNION_TYPE) + WALK_SUBTREE (DECL_QUALIFIER (field)); + } + } + } + + else if (code != EXIT_BLOCK_EXPR + && code != SAVE_EXPR + && code != BIND_EXPR + && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))) { int i, len; @@ -2068,24 +2121,8 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_) #endif } - /* Look inside the sizes of decls, but we don't ever use the values for - FIELD_DECL and RESULT_DECL, so ignore them. */ - else if (TREE_CODE_CLASS (code) == 'd' - && code != FIELD_DECL && code != RESULT_DECL) - { - WALK_SUBTREE (DECL_SIZE (*tp)); - WALK_SUBTREE (DECL_SIZE_UNIT (*tp)); - WALK_SUBTREE_TAIL (TREE_TYPE (*tp)); - } else { - if (TREE_CODE_CLASS (code) == 't') - { - WALK_SUBTREE (TYPE_SIZE (*tp)); - WALK_SUBTREE (TYPE_SIZE_UNIT (*tp)); - /* Also examine various special fields, below. */ - } - /* Not one of the easy cases. We must explicitly go through the children. */ switch (code) @@ -2107,12 +2144,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_) above. */ break; - case POINTER_TYPE: - case REFERENCE_TYPE: - case COMPLEX_TYPE: - WALK_SUBTREE_TAIL (TREE_TYPE (*tp)); - break; - case TREE_LIST: WALK_SUBTREE (TREE_VALUE (*tp)); WALK_SUBTREE_TAIL (TREE_CHAIN (*tp)); @@ -2140,6 +2171,44 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_) case CONSTRUCTOR: WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp)); + case EXIT_BLOCK_EXPR: + WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 1)); + + case SAVE_EXPR: + WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0)); + + case BIND_EXPR: + { + tree decl; + for (decl = BIND_EXPR_VARS (*tp); decl; decl = TREE_CHAIN (decl)) + { + /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk + into declarations that are just mentioned, rather than + declared; they don't really belong to this part of the tree. + And, we can see cycles: the initializer for a declaration + can refer to the declaration itself. */ + WALK_SUBTREE (DECL_INITIAL (decl)); + WALK_SUBTREE (DECL_SIZE (decl)); + WALK_SUBTREE (DECL_SIZE_UNIT (decl)); + WALK_SUBTREE (TREE_TYPE (decl)); + } + WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp)); + } + + case STATEMENT_LIST: + { + tree_stmt_iterator i; + for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i)) + WALK_SUBTREE (*tsi_stmt_ptr (i)); + } + break; + + case POINTER_TYPE: + case REFERENCE_TYPE: + case COMPLEX_TYPE: + WALK_SUBTREE_TAIL (TREE_TYPE (*tp)); + break; + case METHOD_TYPE: WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp)); @@ -2148,38 +2217,14 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_) case FUNCTION_TYPE: WALK_SUBTREE (TREE_TYPE (*tp)); { - tree arg = TYPE_ARG_TYPES (*tp); + tree arg; /* We never want to walk into default arguments. */ - for (; arg; arg = TREE_CHAIN (arg)) + for (arg = TYPE_ARG_TYPES (*tp); arg; arg = TREE_CHAIN (arg)) WALK_SUBTREE (TREE_VALUE (arg)); } break; - case RECORD_TYPE: - case UNION_TYPE: - case QUAL_UNION_TYPE: - { - tree field; - - for (field = TYPE_FIELDS (*tp); field; field = TREE_CHAIN (field)) - { - /* We would like to look at the type of the field, but we - can easily get infinite recursion. So assume it's - pointed to elsewhere in the tree. Also, ignore things that - aren't fields. */ - if (TREE_CODE (field) != FIELD_DECL) - continue; - - WALK_SUBTREE (DECL_FIELD_OFFSET (field)); - WALK_SUBTREE (DECL_SIZE (field)); - WALK_SUBTREE (DECL_SIZE_UNIT (field)); - if (code == QUAL_UNION_TYPE) - WALK_SUBTREE (DECL_QUALIFIER (field)); - } - } - break; - case ARRAY_TYPE: /* Don't follow this nodes's type if a pointer for fear that we'll have infinite recursion. Those types are uninteresting anyway. */ @@ -2200,38 +2245,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_) WALK_SUBTREE (TREE_TYPE (*tp)); WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp)); - case EXIT_BLOCK_EXPR: - WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 1)); - - case SAVE_EXPR: - WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0)); - - case BIND_EXPR: - { - tree decl; - for (decl = BIND_EXPR_VARS (*tp); decl; decl = TREE_CHAIN (decl)) - { - /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk - into declarations that are just mentioned, rather than - declared; they don't really belong to this part of the tree. - And, we can see cycles: the initializer for a declaration - can refer to the declaration itself. */ - WALK_SUBTREE (DECL_INITIAL (decl)); - WALK_SUBTREE (DECL_SIZE (decl)); - WALK_SUBTREE (DECL_SIZE_UNIT (decl)); - WALK_SUBTREE (TREE_TYPE (decl)); - } - WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp)); - } - - case STATEMENT_LIST: - { - tree_stmt_iterator i; - for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i)) - WALK_SUBTREE (*tsi_stmt_ptr (i)); - } - break; - default: /* ??? This could be a language-defined node. We really should make a hook for it, but right now just ignore it. */ @@ -2358,34 +2371,20 @@ static tree mark_local_for_remap_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data) { - tree t = *tp; inline_data *id = (inline_data *) data; - tree decl; /* Don't walk into types. */ - if (TYPE_P (t)) - { - *walk_subtrees = 0; - return NULL_TREE; - } - - if (TREE_CODE (t) == LABEL_EXPR) - decl = TREE_OPERAND (t, 0); - else - /* We don't need to handle anything else ahead of time. */ - decl = NULL_TREE; + if (TYPE_P (*tp)) + *walk_subtrees = 0; - if (decl) + else if (TREE_CODE (*tp) == LABEL_EXPR) { - tree copy; - - /* Make a copy. */ - copy = copy_decl_for_inlining (decl, - DECL_CONTEXT (decl), - DECL_CONTEXT (decl)); + tree decl = TREE_OPERAND (*tp, 0); - /* Remember the copy. */ - insert_decl_map (id, decl, copy); + /* Copy the decl and remember the copy. */ + insert_decl_map (id, decl, + copy_decl_for_inlining (decl, DECL_CONTEXT (decl), + DECL_CONTEXT (decl))); } return NULL_TREE; diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 7d195cc2e75..d1899981c1f 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -1763,7 +1763,7 @@ discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees, if (TYPE_P (t) || DECL_P (t)) *walk_subtrees = 0; - if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) + else if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) { while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) && is_gimple_min_invariant (TREE_OPERAND (t, 1)) diff --git a/gcc/tree.c b/gcc/tree.c index 25431d4495b..e0a1c46ea36 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1856,6 +1856,10 @@ has_cleanups (tree exp) } return 0; + case DECL_EXPR: + return (DECL_INITIAL (DECL_EXPR_DECL (exp)) + && has_cleanups (DECL_INITIAL (DECL_EXPR_DECL (exp)))); + default: break; } diff --git a/gcc/tree.def b/gcc/tree.def index f7dabaf46c8..422817d3215 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -805,6 +805,9 @@ DEFTREECODE (TRY_FINALLY_EXPR, "try_finally", 's', 2) /* These types of expressions have no useful value, and always have side effects. */ +/* Used to represent a local declaration. The operand is DECL_EXPR_DECL. */ +DEFTREECODE (DECL_EXPR, "decl_expr", 's', 1) + /* A label definition, encapsulated as a statement. Operand 0 is the LABEL_DECL node for the label that appears here. The type should be void and the value should be ignored. */ diff --git a/gcc/tree.h b/gcc/tree.h index a369827f461..57d1970b7c7 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1065,6 +1065,10 @@ struct tree_vec GTY(()) #define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 1) #define TARGET_EXPR_CLEANUP(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 2) +/* DECL_EXPR accessor. This gives access to the DECL associated with + the given declaration statement. */ +#define DECL_EXPR_DECL(NODE) TREE_OPERAND (DECL_EXPR_CHECK (NODE), 0) + #define EXIT_EXPR_COND(NODE) TREE_OPERAND (EXIT_EXPR_CHECK (NODE), 0) /* SWITCH_EXPR accessors. These give access to the condition, body and -- 2.30.2