cp-tree.h (begin_init_stmts): Declare.
authorMark Mitchell <mark@codesourcery.com>
Mon, 30 Aug 1999 18:54:20 +0000 (18:54 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 30 Aug 1999 18:54:20 +0000 (18:54 +0000)
* 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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/init.c
gcc/testsuite/g++.old-deja/g++.pt/crash53.C [new file with mode: 0644]

index 4194bac..a77ca97 100644 (file)
@@ -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.
index ac5ecdc..82fb68d 100644 (file)
@@ -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 */
 
index 388c7b8..73e76dd 100644 (file)
@@ -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;
 }
 
index 9265ff9..08eaf0b 100644 (file)
@@ -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 (file)
index 0000000..2324a37
--- /dev/null
@@ -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>();