summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2003-08-21 03:20:54 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2003-08-21 03:20:54 +0000
commitb9e35020feaf774035c781ec87c721a1c43fc4e4 (patch)
tree4cc303464599d82c38a0015e1eadce58b1248567
parent9ad4b12bf6689566f6e6c7706fef5f39fe8c0595 (diff)
downloadgcc-b9e35020feaf774035c781ec87c721a1c43fc4e4.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70635 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/semantics.c67
-rw-r--r--gcc/cp/tree.c5
4 files changed, 56 insertions, 26 deletions
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 <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>
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);