From: Jason Merrill Date: Thu, 21 Aug 2003 03:20:54 +0000 (-0400) Subject: semantics.c (simplify_aggr_init_expr): Split out from simplify_aggr_init_exprs_r. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9eeb200f8a1270e84d0b1c56aa31d5a93e7a3e86;p=gcc.git semantics.c (simplify_aggr_init_expr): Split out from simplify_aggr_init_exprs_r. * semantics.c (simplify_aggr_init_expr): Split out from simplify_aggr_init_exprs_r. Convert slot address to match the return type. * cp-tree.h: Declare it. * tree.c (cp_copy_res_decl_for_inlining): Don't clobber the DECL_NAME of a user variable. From-SVN: r70635 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7dcf9c2dc29..59a81c13d8c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2003-08-20 Jason Merrill + + * semantics.c (simplify_aggr_init_expr): Split out from + simplify_aggr_init_exprs_r. Convert slot address to match + the return type. + * cp-tree.h: Declare it. + * tree.c (cp_copy_res_decl_for_inlining): Don't clobber the + DECL_NAME of a user variable. + 2003-08-20 Nathan Sidwell PR c++/11945 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 396dc0fe0d4..9cda7696e77 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4147,6 +4147,7 @@ extern tree check_template_template_default_arg (tree); extern void expand_or_defer_fn (tree); extern void check_accessibility_of_qualified_id (tree, tree, tree); extern tree finish_qualified_id_expr (tree, tree, bool, bool); +extern void simplify_aggr_init_expr (tree *); /* in tree.c */ extern void lang_check_failed (const char *, int, diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 78a7f06413a..d5de76aad44 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2713,37 +2713,46 @@ cp_expand_stmt (tree t) static tree simplify_aggr_init_exprs_r (tree* tp, - int* walk_subtrees ATTRIBUTE_UNUSED , - void* data ATTRIBUTE_UNUSED ) + int* walk_subtrees, + void* data ATTRIBUTE_UNUSED) { - tree aggr_init_expr; - tree call_expr; - tree fn; - tree args; - tree slot; - tree type; - enum style_t { ctor, arg, pcc } style; - - aggr_init_expr = *tp; /* We don't need to walk into types; there's nothing in a type that needs simplification. (And, furthermore, there are places we actively don't want to go. For example, we don't want to wander into the default arguments for a FUNCTION_DECL that appears in a CALL_EXPR.) */ - if (TYPE_P (aggr_init_expr)) + if (TYPE_P (*tp)) { *walk_subtrees = 0; return NULL_TREE; } /* Only AGGR_INIT_EXPRs are interesting. */ - else if (TREE_CODE (aggr_init_expr) != AGGR_INIT_EXPR) + else if (TREE_CODE (*tp) != AGGR_INIT_EXPR) return NULL_TREE; + simplify_aggr_init_expr (tp); + + /* Keep iterating. */ + return NULL_TREE; +} + +/* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This + function is broken out from the above for the benefit of the tree-ssa + project. */ + +void +simplify_aggr_init_expr (tree *tp) +{ + tree aggr_init_expr = *tp; + /* Form an appropriate CALL_EXPR. */ - fn = TREE_OPERAND (aggr_init_expr, 0); - args = TREE_OPERAND (aggr_init_expr, 1); - slot = TREE_OPERAND (aggr_init_expr, 2); - type = TREE_TYPE (aggr_init_expr); + tree fn = TREE_OPERAND (aggr_init_expr, 0); + tree args = TREE_OPERAND (aggr_init_expr, 1); + tree slot = TREE_OPERAND (aggr_init_expr, 2); + tree type = TREE_TYPE (aggr_init_expr); + + tree call_expr; + enum style_t { ctor, arg, pcc } style; if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr)) style = ctor; @@ -2762,15 +2771,26 @@ simplify_aggr_init_exprs_r (tree* tp, { /* Pass the address of the slot. If this is a constructor, we replace the first argument; otherwise, we tack on a new one. */ + tree addr; + if (style == ctor) args = TREE_CHAIN (args); cxx_mark_addressable (slot); - args = tree_cons (NULL_TREE, - build1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (slot)), - slot), - args); + addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (slot)), slot); + if (style == arg) + { + /* The return type might have different cv-quals from the slot. */ + tree fntype = TREE_TYPE (TREE_TYPE (fn)); +#ifdef ENABLE_CHECKING + if (TREE_CODE (fntype) != FUNCTION_TYPE + && TREE_CODE (fntype) != METHOD_TYPE) + abort (); +#endif + addr = convert (build_pointer_type (TREE_TYPE (fntype)), addr); + } + + args = tree_cons (NULL_TREE, addr, args); } call_expr = build (CALL_EXPR, @@ -2801,9 +2821,6 @@ simplify_aggr_init_exprs_r (tree* tp, /* Replace the AGGR_INIT_EXPR with the CALL_EXPR. */ TREE_CHAIN (call_expr) = TREE_CHAIN (aggr_init_expr); *tp = call_expr; - - /* Keep iterating. */ - return NULL_TREE; } /* Emit all thunks to FN that should be emitted when FN is emitted. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 64676fdf544..cd1ea240c49 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2193,7 +2193,10 @@ cp_copy_res_decl_for_inlining (tree result, /* We have a named return value; copy the name and source position so we can get reasonable debugging information, and register the return variable as its equivalent. */ - if (TREE_CODE (var) == VAR_DECL) + if (TREE_CODE (var) == VAR_DECL + /* But not if we're initializing a variable from the + enclosing function which already has its own name. */ + && DECL_NAME (var) == NULL_TREE) { DECL_NAME (var) = DECL_NAME (nrv); DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);