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
This commit is contained in:
parent
3c5c0849a9
commit
8d1e67c6c4
5 changed files with 54 additions and 4 deletions
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
26
gcc/cp/cvt.c
26
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
16
gcc/testsuite/g++.old-deja/g++.pt/crash53.C
Normal file
16
gcc/testsuite/g++.old-deja/g++.pt/crash53.C
Normal file
|
@ -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>();
|
Loading…
Add table
Reference in a new issue