cvt.c (convert_lvalue): New fn.
authorJason Merrill <jason@redhat.com>
Thu, 5 Jul 2001 15:39:36 +0000 (11:39 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 5 Jul 2001 15:39:36 +0000 (11:39 -0400)
        * cvt.c (convert_lvalue): New fn.
        * cp-tree.h: Declare it.
        * method.c (do_build_assign_ref): Use it.
        (do_build_copy_constructor): Convert parm to base types
        before calling base constructors.

        * typeck.c (check_return_expr): Check DECL_ALIGN instead of
        DECL_USER_ALIGN.  Check flag_elide_constructors instead of
        optimize.
        * semantics.c (cp_expand_stmt): Don't destroy the named return value.

From-SVN: r43780

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/method.c
gcc/cp/semantics.c
gcc/cp/typeck.c

index dfe82c029f87832943d7d8de0bfdbbb8c4077232..5e6195cf5322bcd6789a6f4a6e6b30491cadf5a8 100644 (file)
@@ -1,3 +1,16 @@
+2001-07-05  Jason Merrill  <jason_merrill@redhat.com>
+
+       * cvt.c (convert_lvalue): New fn.
+       * cp-tree.h: Declare it.
+       * method.c (do_build_assign_ref): Use it.
+       (do_build_copy_constructor): Convert parm to base types
+       before calling base constructors.
+
+       * typeck.c (check_return_expr): Check DECL_ALIGN instead of
+       DECL_USER_ALIGN.  Check flag_elide_constructors instead of
+       optimize.
+       * semantics.c (cp_expand_stmt): Don't destroy the named return value.
+
 2001-07-02  Nathan Sidwell  <nathan@codesourcery.com>
 
        * optimize.c (optimize_inline_calls): New function, broken out
index cebc9262354cb0b3485695c4b8df20aadd0aa0f3..2ccb3b71655a18da48522d7979548fa5ab25a84e 100644 (file)
@@ -3735,6 +3735,7 @@ extern tree get_primary_binfo                   PARAMS ((tree));
 /* in cvt.c */
 extern tree convert_to_reference               PARAMS ((tree, tree, int, int, tree));
 extern tree convert_from_reference             PARAMS ((tree));
+extern tree convert_lvalue                     PARAMS ((tree, tree));
 extern tree convert_pointer_to_real            PARAMS ((tree, tree));
 extern tree convert_pointer_to                 PARAMS ((tree, tree));
 extern tree ocp_convert                                PARAMS ((tree, tree, int, int));
index 1dff9e5aadf49e4dc436fcc5b642af7087f2e431..33be568ed14feb56c18a6589ef6c466d6ba1b4bc 100644 (file)
@@ -597,6 +597,20 @@ convert_from_reference (val)
     return build_indirect_ref (val, NULL);
   return val;
 }
+
+/* Implicitly convert the lvalue EXPR to another lvalue of type TOTYPE,
+   preserving cv-qualification.  */
+
+tree
+convert_lvalue (totype, expr)
+     tree totype, expr;
+{
+  totype = cp_build_qualified_type (totype, TYPE_QUALS (TREE_TYPE (expr)));
+  totype = build_reference_type (totype);
+  expr = convert_to_reference (totype, expr, CONV_IMPLICIT, LOOKUP_NORMAL,
+                              NULL_TREE);
+  return convert_from_reference (expr);
+}
 \f
 /* Call this when we know (for any reason) that expr is not, in fact,
    zero.  This routine is like convert_pointer_to, but it pays
index ceb569c70d7f3615d2c82e4a4049e4caec5639d2..6f6a14b53a3898a3e19d7fbffe8f85fd6978fd14 100644 (file)
@@ -557,25 +557,31 @@ do_build_copy_constructor (fndecl)
       int cvquals = CP_TYPE_QUALS (TREE_TYPE (parm));
       int i;
 
-      /* Initialize all the base-classes.  */
+      /* Initialize all the base-classes with the parameter converted to
+         their type so that we get their copy constructor and not another
+         constructor that takes current_class_type.  */
       for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;
           t = TREE_CHAIN (t))
-       base_init_list 
-         = tree_cons (BINFO_TYPE (TREE_VALUE (t)), parm, 
-                      base_init_list);
+       {
+         tree type = BINFO_TYPE (TREE_VALUE (t));
+         base_init_list = tree_cons (type, convert_lvalue (type, parm),
+                                     base_init_list);
+       }
+
       for (i = 0; i < n_bases; ++i)
        {
          t = TREE_VEC_ELT (binfos, i);
          if (TREE_VIA_VIRTUAL (t))
            continue; 
 
-         base_init_list 
-           = tree_cons (BINFO_TYPE (t), parm, base_init_list);
+         t = BINFO_TYPE (t);
+         base_init_list = tree_cons (t, convert_lvalue (t, parm),
+                                     base_init_list);
        }
 
       for (; fields; fields = TREE_CHAIN (fields))
        {
-         tree init, t;
+         tree init;
          tree field = fields;
 
          if (TREE_CODE (field) != FIELD_DECL)
@@ -645,12 +651,7 @@ do_build_assign_ref (fndecl)
       for (i = 0; i < n_bases; ++i)
        {
          tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
-         tree p = build_qualified_type (basetype, cvquals);
-
-         p = convert_to_reference
-           (build_reference_type (p), parm,
-            CONV_IMPLICIT, LOOKUP_COMPLAIN, NULL_TREE);
-         p = convert_from_reference (p);
+         tree p = convert_lvalue (basetype, parm);
          p = build_member_call (basetype, ansi_assopname (NOP_EXPR),
                                 build_tree_list (NULL_TREE, p));
          finish_expr_stmt (p);
index 050e1be314c7719fea38e7b336da7fb3eb75b757..66f36ab2c5c03b606bb2e0f3b9313c564d3e1e31 100644 (file)
@@ -2156,7 +2156,9 @@ cp_expand_stmt (t)
   switch (TREE_CODE (t))
     {
     case CLEANUP_STMT:
-      genrtl_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t));
+      /* Don't destroy the chosen named return value.  */
+      if (CLEANUP_DECL (t) != current_function_return_value)
+       genrtl_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t));
       break;
 
     case CTOR_STMT:
index cb1146ef7d3c961eba27cad8ec3304cb2b8db71b..43f38f3e1de0074e6b66d968440c334d964b47bb 100644 (file)
@@ -6684,7 +6684,7 @@ check_return_expr (retval)
      returned expression uses the chosen variable somehow.  And people expect
      this restriction, anyway.  (jason 2000-11-19) */
 
-  if (fn_returns_value_p && optimize)
+  if (fn_returns_value_p && flag_elide_constructors)
     {
       if (retval != NULL_TREE
          && (current_function_return_value == NULL_TREE
@@ -6692,7 +6692,8 @@ check_return_expr (retval)
          && TREE_CODE (retval) == VAR_DECL
          && DECL_CONTEXT (retval) == current_function_decl
          && ! TREE_STATIC (retval)
-         && ! DECL_USER_ALIGN (retval)
+         && (DECL_ALIGN (retval)
+             == DECL_ALIGN (DECL_RESULT (current_function_decl)))
          && same_type_p (TREE_TYPE (retval),
                          TREE_TYPE (TREE_TYPE (current_function_decl))))
        current_function_return_value = retval;