Commit 9eeb200f by Jason Merrill Committed by Jason Merrill

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
parent e50084fa
2003-08-20 Jason Merrill <jason@redhat.com>
* 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 <nathan@codesourcery.com> 2003-08-20 Nathan Sidwell <nathan@codesourcery.com>
PR c++/11945 PR c++/11945
......
...@@ -4147,6 +4147,7 @@ extern tree check_template_template_default_arg (tree); ...@@ -4147,6 +4147,7 @@ extern tree check_template_template_default_arg (tree);
extern void expand_or_defer_fn (tree); extern void expand_or_defer_fn (tree);
extern void check_accessibility_of_qualified_id (tree, tree, tree); extern void check_accessibility_of_qualified_id (tree, tree, tree);
extern tree finish_qualified_id_expr (tree, tree, bool, bool); extern tree finish_qualified_id_expr (tree, tree, bool, bool);
extern void simplify_aggr_init_expr (tree *);
/* in tree.c */ /* in tree.c */
extern void lang_check_failed (const char *, int, extern void lang_check_failed (const char *, int,
......
...@@ -2713,37 +2713,46 @@ cp_expand_stmt (tree t) ...@@ -2713,37 +2713,46 @@ cp_expand_stmt (tree t)
static tree static tree
simplify_aggr_init_exprs_r (tree* tp, simplify_aggr_init_exprs_r (tree* tp,
int* walk_subtrees ATTRIBUTE_UNUSED , int* walk_subtrees,
void* data ATTRIBUTE_UNUSED ) 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 /* We don't need to walk into types; there's nothing in a type that
needs simplification. (And, furthermore, there are places we needs simplification. (And, furthermore, there are places we
actively don't want to go. For example, we don't want to wander 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 into the default arguments for a FUNCTION_DECL that appears in a
CALL_EXPR.) */ CALL_EXPR.) */
if (TYPE_P (aggr_init_expr)) if (TYPE_P (*tp))
{ {
*walk_subtrees = 0; *walk_subtrees = 0;
return NULL_TREE; return NULL_TREE;
} }
/* Only AGGR_INIT_EXPRs are interesting. */ /* 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; 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. */ /* Form an appropriate CALL_EXPR. */
fn = TREE_OPERAND (aggr_init_expr, 0); tree fn = TREE_OPERAND (aggr_init_expr, 0);
args = TREE_OPERAND (aggr_init_expr, 1); tree args = TREE_OPERAND (aggr_init_expr, 1);
slot = TREE_OPERAND (aggr_init_expr, 2); tree slot = TREE_OPERAND (aggr_init_expr, 2);
type = TREE_TYPE (aggr_init_expr); 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)) if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
style = ctor; style = ctor;
...@@ -2762,15 +2771,26 @@ simplify_aggr_init_exprs_r (tree* tp, ...@@ -2762,15 +2771,26 @@ simplify_aggr_init_exprs_r (tree* tp,
{ {
/* Pass the address of the slot. If this is a constructor, we /* Pass the address of the slot. If this is a constructor, we
replace the first argument; otherwise, we tack on a new one. */ replace the first argument; otherwise, we tack on a new one. */
tree addr;
if (style == ctor) if (style == ctor)
args = TREE_CHAIN (args); args = TREE_CHAIN (args);
cxx_mark_addressable (slot); cxx_mark_addressable (slot);
args = tree_cons (NULL_TREE, addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (slot)), slot);
build1 (ADDR_EXPR, if (style == arg)
build_pointer_type (TREE_TYPE (slot)), {
slot), /* The return type might have different cv-quals from the slot. */
args); 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, call_expr = build (CALL_EXPR,
...@@ -2801,9 +2821,6 @@ simplify_aggr_init_exprs_r (tree* tp, ...@@ -2801,9 +2821,6 @@ simplify_aggr_init_exprs_r (tree* tp,
/* Replace the AGGR_INIT_EXPR with the CALL_EXPR. */ /* Replace the AGGR_INIT_EXPR with the CALL_EXPR. */
TREE_CHAIN (call_expr) = TREE_CHAIN (aggr_init_expr); TREE_CHAIN (call_expr) = TREE_CHAIN (aggr_init_expr);
*tp = call_expr; *tp = call_expr;
/* Keep iterating. */
return NULL_TREE;
} }
/* Emit all thunks to FN that should be emitted when FN is emitted. */ /* Emit all thunks to FN that should be emitted when FN is emitted. */
......
...@@ -2193,7 +2193,10 @@ cp_copy_res_decl_for_inlining (tree result, ...@@ -2193,7 +2193,10 @@ cp_copy_res_decl_for_inlining (tree result,
/* We have a named return value; copy the name and source /* We have a named return value; copy the name and source
position so we can get reasonable debugging information, and position so we can get reasonable debugging information, and
register the return variable as its equivalent. */ 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_NAME (var) = DECL_NAME (nrv);
DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv); DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment