aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-08-30 18:54:20 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-08-30 18:54:20 +0000
commit8d1e67c6c4542d8e9f0b6b509d875a61bca98d66 (patch)
tree14f516236d17033bb3856363e7c682c523297efa /gcc
parent3c5c0849a9edab2c0c847205d4e9af84376b8240 (diff)
downloadgcc-8d1e67c6c4542d8e9f0b6b509d875a61bca98d66.zip
gcc-8d1e67c6c4542d8e9f0b6b509d875a61bca98d66.tar.gz
gcc-8d1e67c6c4542d8e9f0b6b509d875a61bca98d66.tar.bz2
cp-tree.h (begin_init_stmts): Declare.
* cp-tree.h (begin_init_stmts): Declare. (finish_init_stmts): Likewise. * cvt.c (build_up_reference): Wrap the declaration of a temporary in a statement-expression so that we will see it when expanding tree structure later. * init.c (begin_init_stmts): Don't make it static. (finish_init_stmts): Likewise. From-SVN: r28984
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/cvt.c26
-rw-r--r--gcc/cp/init.c6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash53.C16
5 files changed, 54 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4194bac..a77ca97 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,13 @@
1999-08-30 Mark Mitchell <mark@codesourcery.com>
+ * cp-tree.h (begin_init_stmts): Declare.
+ (finish_init_stmts): Likewise.
+ * cvt.c (build_up_reference): Wrap the declaration of a temporary
+ in a statement-expression so that we will see it when expanding
+ tree structure later.
+ * init.c (begin_init_stmts): Don't make it static.
+ (finish_init_stmts): Likewise.
+
* cp-tree.h (start_handler_parms): New function.
(expand_start_catch_block): Take only one parameter.
(start_handler_parms): New function.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index ac5ecdc..82fb68d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3129,6 +3129,8 @@ extern tree build_delete PROTO((tree, tree, tree, int, int));
extern tree build_vbase_delete PROTO((tree, tree));
extern tree build_vec_delete PROTO((tree, tree, tree, tree, int));
extern tree create_temporary_var PROTO((tree));
+extern void begin_init_stmts PROTO((tree *, tree *));
+extern tree finish_init_stmts PROTO((tree, tree));
/* in input.c */
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 388c7b8..73e76dd 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -339,11 +339,15 @@ build_up_reference (type, arg, flags)
tree rval;
tree argtype = TREE_TYPE (arg);
tree target_type = TREE_TYPE (type);
+ tree stmt_expr = NULL_TREE;
my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 187);
if ((flags & DIRECT_BIND) && ! real_lvalue_p (arg))
{
+ tree compound_stmt;
+
+ /* Create a new temporary variable. */
tree targ = arg;
if (toplevel_bindings_p ())
arg = get_temp_name (argtype, 1);
@@ -351,10 +355,25 @@ build_up_reference (type, arg, flags)
{
arg = pushdecl (build_decl (VAR_DECL, NULL_TREE, argtype));
DECL_ARTIFICIAL (arg) = 1;
+ /* Generate code to initialize it. We wrap it in a
+ statement-expression so that when we are building a
+ statement-tree we will have a representation of this
+ declaration. */
+ begin_init_stmts (&stmt_expr, &compound_stmt);
}
+
+ /* Process the initializer for the declaration. */
DECL_INITIAL (arg) = targ;
cp_finish_decl (arg, targ, NULL_TREE, 0,
LOOKUP_ONLYCONVERTING|DIRECT_BIND);
+
+ /* And wrap up the statement-expression, if necessary. */
+ if (!toplevel_bindings_p ())
+ {
+ if (building_stmt_tree ())
+ add_decl_stmt (arg);
+ stmt_expr = finish_init_stmts (stmt_expr, compound_stmt);
+ }
}
else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg))
{
@@ -389,6 +408,13 @@ build_up_reference (type, arg, flags)
= convert_to_pointer_force (build_pointer_type (target_type), rval);
rval = build1 (NOP_EXPR, type, rval);
TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0));
+
+ /* If we created and initialized a new temporary variable, add the
+ representation of that initialization to the RVAL. */
+ if (stmt_expr)
+ rval = build (COMPOUND_EXPR, TREE_TYPE (rval), stmt_expr, rval);
+
+ /* And return the result. */
return rval;
}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 9265ff9..08eaf0b 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -60,8 +60,6 @@ static tree initializing_context PROTO((tree));
static tree build_java_class_ref PROTO((tree));
static void expand_cleanup_for_base PROTO((tree, tree));
static tree get_temp_regvar PROTO((tree, tree));
-static void begin_init_stmts PROTO((tree *, tree *));
-static tree finish_init_stmts PROTO((tree, tree));
/* Cache the identifier nodes for the magic field of a new cookie. */
static tree nc_nelts_field_id;
@@ -1007,7 +1005,7 @@ expand_member_init (exp, name, init)
pass them back to finish_init_stmts when the expression is
complete. */
-static void
+void
begin_init_stmts (stmt_expr_p, compound_stmt_p)
tree *stmt_expr_p;
tree *compound_stmt_p;
@@ -1020,7 +1018,7 @@ begin_init_stmts (stmt_expr_p, compound_stmt_p)
/* Finish out the statement-expression begun by the previous call to
begin_init_stmts. Returns the statement-expression itself. */
-static tree
+tree
finish_init_stmts (stmt_expr, compound_stmt)
tree stmt_expr;
tree compound_stmt;
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash53.C b/gcc/testsuite/g++.old-deja/g++.pt/crash53.C
new file mode 100644
index 0000000..2324a37
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash53.C
@@ -0,0 +1,16 @@
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+struct S
+{
+};
+
+S g ();
+
+template <class T>
+void f ()
+{
+ const S& s = g ();
+}
+
+template void f<int>();