error.c (dump_function_name): Don't let the user see __comp_ctor.
authorJason Merrill <jason@redhat.com>
Sat, 9 Dec 2000 18:34:12 +0000 (13:34 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 9 Dec 2000 18:34:12 +0000 (13:34 -0500)
        * error.c (dump_function_name): Don't let the user see __comp_ctor.

        Clean up copy-initialization in overloading code.
        * call.c (build_user_type_conversion_1): Die if we are asked to
        convert to the same or a base type.
        (implicit_conversion): Avoid doing so.  Lose reference binding code.
        (convert_like_real): Treat BASE_CONV and RVALUE_CONV as implicit
        direct-initialization.  Also do direct-init part of copy-init.
        (build_user_type_conversion): Don't provide context to convert_like.
        * cvt.c (ocp_convert): build_user_type_conversion will now provide
        the constructor call for copy-init.

        * pt.c (tsubst_decl): Call clone_function_decl here if this is an
        instantiation of a member template.
        (do_decl_instantiation): Not here.

From-SVN: r38158

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cvt.c
gcc/cp/error.c
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.law/cvt7.C
gcc/testsuite/g++.old-deja/g++.mike/p5469.C
gcc/testsuite/g++.old-deja/g++.mike/p5469a.C

index 00f954910504a0a7a04e9e7f42917675076c81e2..0ef0b3d44816bc254e8a73f75932b6c2c87edd8b 100644 (file)
@@ -1,3 +1,21 @@
+2000-12-08  Jason Merrill  <jason@redhat.com>
+
+       * error.c (dump_function_name): Don't let the user see __comp_ctor.
+
+       Clean up copy-initialization in overloading code.
+       * call.c (build_user_type_conversion_1): Die if we are asked to
+       convert to the same or a base type.
+       (implicit_conversion): Avoid doing so.  Lose reference binding code.
+       (convert_like_real): Treat BASE_CONV and RVALUE_CONV as implicit
+       direct-initialization.  Also do direct-init part of copy-init.
+       (build_user_type_conversion): Don't provide context to convert_like.
+       * cvt.c (ocp_convert): build_user_type_conversion will now provide
+       the constructor call for copy-init.
+
+       * pt.c (tsubst_decl): Call clone_function_decl here if this is an
+       instantiation of a member template.
+       (do_decl_instantiation): Not here.
+
 2000-12-07  Nathan Sidwell  <nathan@codesourcery.com>
 
        * class.c (check_field_decls): Don't special case anonymous
 
        * except.c (expand_throw): Use push_throw_library_fn for _Jv_Throw.
 
-       * pt.c (tsubst_decl): Call clone_function_decl here.
-       (do_decl_instantiation): Not here.
        * class.c (clone_function_decl): Robustify.
 
 2000-12-04  Michael Matz  <matzmich@cs.tu-berlin.de>
index cbe345a3f05961320f82bc5d8016d083c1b8e73f..2f8a9dc7ed66031092a785be3c2f8fd4b69e1e45 100644 (file)
@@ -1237,29 +1237,18 @@ implicit_conversion (to, from, expr, flags)
   if (conv)
     ;
   else if (expr != NULL_TREE
-          && (IS_AGGR_TYPE (non_reference (from))
-              || IS_AGGR_TYPE (non_reference (to)))
+          && (IS_AGGR_TYPE (from)
+              || IS_AGGR_TYPE (to))
           && (flags & LOOKUP_NO_CONVERSION) == 0)
     {
       cand = build_user_type_conversion_1
        (to, expr, LOOKUP_ONLYCONVERTING);
       if (cand)
        conv = cand->second_conv;
-      if ((! conv || ICS_BAD_FLAG (conv))
-         && TREE_CODE (to) == REFERENCE_TYPE
-         && (flags & LOOKUP_NO_TEMP_BIND) == 0)
-       {
-         cand = build_user_type_conversion_1
-           (TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING);
-         if (cand)
-           {
-             if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (to)))
-               ICS_BAD_FLAG (cand->second_conv) = 1;
-             if (!conv || (ICS_BAD_FLAG (conv)
-                           > ICS_BAD_FLAG (cand->second_conv)))
-               conv = build_conv (REF_BIND, to, cand->second_conv);
-           }
-       }
+
+      /* We used to try to bind a reference to a temporary here, but that
+        is now handled by the recursive call to this function at the end
+        of reference_binding.  */
     }
 
   return conv;
@@ -2325,6 +2314,13 @@ build_user_type_conversion_1 (totype, expr, flags)
   tree args = NULL_TREE;
   tree templates = NULL_TREE;
 
+  /* We represent conversion within a hierarchy using RVALUE_CONV and
+     BASE_CONV, as specified by [over.best.ics]; these become plain
+     constructor calls, as specified in [dcl.init].  */
+  if (IS_AGGR_TYPE (fromtype) && IS_AGGR_TYPE (totype)
+      && DERIVED_FROM_P (totype, fromtype))
+    abort ();
+
   if (IS_AGGR_TYPE (totype))
     ctors = lookup_fnfields (TYPE_BINFO (totype),
                             (flag_new_abi 
@@ -2332,8 +2328,7 @@ build_user_type_conversion_1 (totype, expr, flags)
                              : ctor_identifier),
                             0);
 
-  if (IS_AGGR_TYPE (fromtype)
-      && (! IS_AGGR_TYPE (totype) || ! DERIVED_FROM_P (totype, fromtype)))
+  if (IS_AGGR_TYPE (fromtype))
     convs = lookup_conversions (fromtype);
 
   candidates = 0;
@@ -2509,9 +2504,7 @@ build_user_type_conversion (totype, expr, flags)
     {
       if (TREE_CODE (cand->second_conv) == AMBIG_CONV)
        return error_mark_node;
-      return convert_from_reference
-              (convert_like_with_context
-                (cand->second_conv, expr, cand->fn, 0));
+      return convert_from_reference (convert_like (cand->second_conv, expr));
     }
   return NULL_TREE;
 }
@@ -3653,6 +3646,11 @@ convert_like_real (convs, expr, fn, argnum, inner)
      int argnum;
      int inner;
 {
+  extern int warningcount, errorcount;
+  int savew, savee;
+
+  tree totype = TREE_TYPE (convs);
+
   if (ICS_BAD_FLAG (convs)
       && TREE_CODE (convs) != USER_CONV
       && TREE_CODE (convs) != AMBIG_CONV
@@ -3672,29 +3670,29 @@ convert_like_real (convs, expr, fn, argnum, inner)
            break;
        }
       return convert_for_initialization
-       (NULL_TREE, TREE_TYPE (convs), expr, LOOKUP_NORMAL,
+       (NULL_TREE, totype, expr, LOOKUP_NORMAL,
         "conversion", fn, argnum);
     }
   
   if (!inner)
     expr = dubious_conversion_warnings
-             (TREE_TYPE (convs), expr, "argument", fn, argnum);
+             (totype, expr, "argument", fn, argnum);
   switch (TREE_CODE (convs))
     {
     case USER_CONV:
       {
        struct z_candidate *cand
          = WRAPPER_PTR (TREE_OPERAND (convs, 1));
-       tree fn = cand->fn;
+       tree convfn = cand->fn;
        tree args;
 
-       if (DECL_CONSTRUCTOR_P (fn))
+       if (DECL_CONSTRUCTOR_P (convfn))
          {
            tree t = build_int_2 (0, 0);
-           TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (fn));
+           TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (convfn));
 
            args = build_tree_list (NULL_TREE, expr);
-           if (DECL_HAS_IN_CHARGE_PARM_P (fn))
+           if (DECL_HAS_IN_CHARGE_PARM_P (convfn))
              args = tree_cons (NULL_TREE, integer_one_node, args);
            args = tree_cons (NULL_TREE, t, args);
          }
@@ -3704,19 +3702,61 @@ convert_like_real (convs, expr, fn, argnum, inner)
 
        /* If this is a constructor or a function returning an aggr type,
           we need to build up a TARGET_EXPR.  */
-       if (DECL_CONSTRUCTOR_P (fn))
-         expr = build_cplus_new (TREE_TYPE (convs), expr);
+       if (DECL_CONSTRUCTOR_P (convfn))
+         expr = build_cplus_new (totype, expr);
+
+       /* The result of the call is then used to direct-initialize the object
+          that is the destination of the copy-initialization.  [dcl.init]
+
+          Note that this step is not reflected in the conversion sequence;
+          it affects the semantics when we actually perform the
+          conversion, but is not considered during overload resolution.
 
+          If the target is a class, that means call a ctor.  */
+       if (IS_AGGR_TYPE (totype))
+         {
+           savew = warningcount, savee = errorcount;
+           expr = build_new_method_call
+             (NULL_TREE, complete_ctor_identifier,
+              build_tree_list (NULL_TREE, expr), TYPE_BINFO (totype),
+              /* Core issue 84, now a DR, says that we don't allow UDCs
+                 for these args (which deliberately breaks copy-init of an
+                 auto_ptr<Base> from an auto_ptr<Derived>).  */
+              LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION);
+
+           /* Tell the user where this failing constructor call came from.  */
+           if (fn)
+             {
+               if (warningcount > savew)
+                 cp_warning
+                   ("  initializing argument %P of `%D' from result of `%D'",
+                    argnum, fn, convfn);
+               else if (errorcount > savee)
+                 cp_error
+                   ("  initializing argument %P of `%D' from result of `%D'",
+                    argnum, fn, convfn);
+             }
+           else
+             {
+               if (warningcount > savew)
+                 cp_warning ("  initializing temporary from result of `%D'",
+                             convfn);
+               else if (errorcount > savee)
+                 cp_error ("  initializing temporary from result of `%D'",
+                           convfn);
+             }
+           expr = build_cplus_new (totype, expr);
+         }
        return expr;
       }
     case IDENTITY_CONV:
       if (type_unknown_p (expr))
-       expr = instantiate_type (TREE_TYPE (convs), expr, itf_complain);
+       expr = instantiate_type (totype, expr, itf_complain);
       return expr;
     case AMBIG_CONV:
       /* Call build_user_type_conversion again for the error.  */
       return build_user_type_conversion
-       (TREE_TYPE (convs), TREE_OPERAND (convs, 0), LOOKUP_NORMAL);
+       (totype, TREE_OPERAND (convs, 0), LOOKUP_NORMAL);
 
     default:
       break;
@@ -3736,7 +3776,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
   switch (TREE_CODE (convs))
     {
     case RVALUE_CONV:
-      if (! IS_AGGR_TYPE (TREE_TYPE (convs)))
+      if (! IS_AGGR_TYPE (totype))
        return expr;
       /* else fall through */
     case BASE_CONV:
@@ -3744,7 +3784,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
        {
          /* We are going to bind a reference directly to a base-class
             subobject of EXPR.  */
-         tree base_ptr = build_pointer_type (TREE_TYPE (convs));
+         tree base_ptr = build_pointer_type (totype);
 
          /* Build an expression for `*((base*) &expr)'.  */
          expr = build_unary_op (ADDR_EXPR, expr, 0);
@@ -3753,35 +3793,27 @@ convert_like_real (convs, expr, fn, argnum, inner)
          return expr;
        }
 
-      {
-       tree cvt_expr = build_user_type_conversion
-         (TREE_TYPE (convs), expr, LOOKUP_NORMAL);
-       if (!cvt_expr) 
-         {
-           /* This can occur if, for example, the EXPR has incomplete
-              type.  We can't check for that before attempting the
-              conversion because the type might be an incomplete
-              array type, which is OK if some constructor for the
-              destination type takes a pointer argument.  */
-           if (!COMPLETE_TYPE_P (TREE_TYPE (expr)))
-             {
-               if (same_type_p (TREE_TYPE (expr), TREE_TYPE (convs)))
-                 incomplete_type_error (expr, TREE_TYPE (expr));
-               else
-                 cp_error ("could not convert `%E' (with incomplete type `%T') to `%T'",
-                           expr, TREE_TYPE (expr), TREE_TYPE (convs));
-             }
-           else
-             cp_error ("could not convert `%E' to `%T'",
-                       expr, TREE_TYPE (convs));
-           return error_mark_node;
-         }
-       return cvt_expr;
-      }
+      /* Copy-initialization where the cv-unqualified version of the source
+        type is the same class as, or a derived class of, the class of the
+        destination [is treated as direct-initialization].  [dcl.init] */
+      if (fn)
+       savew = warningcount, savee = errorcount;
+      expr = build_new_method_call (NULL_TREE, complete_ctor_identifier,
+                                   build_tree_list (NULL_TREE, expr),
+                                   TYPE_BINFO (totype),
+                                   LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING);
+      if (fn)
+       {
+         if (warningcount > savew)
+           cp_warning ("  initializing argument %P of `%D'", argnum, fn);
+         else if (errorcount > savee)
+           cp_error ("  initializing argument %P of `%D'", argnum, fn);
+       }
+      return build_cplus_new (totype, expr);
 
     case REF_BIND:
       {
-       tree ref_type = TREE_TYPE (convs);
+       tree ref_type = totype;
 
        /* If necessary, create a temporary.  */
        if (NEED_TEMPORARY_P (convs))
@@ -3812,13 +3844,13 @@ convert_like_real (convs, expr, fn, argnum, inner)
 
     case QUAL_CONV:
       /* Warn about deprecated conversion if appropriate.  */
-      string_conv_p (TREE_TYPE (convs), expr, 1);
+      string_conv_p (totype, expr, 1);
       break;
       
     default:
       break;
     }
-  return ocp_convert (TREE_TYPE (convs), expr, CONV_IMPLICIT,
+  return ocp_convert (totype, expr, CONV_IMPLICIT,
                      LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
 }
 
index 1672f26f82bc3916ba457c9787b531abe4059a08..e997d11d7bf4862fb1a0d700a58c6da7c5c7bc34 100644 (file)
@@ -841,7 +841,7 @@ ocp_convert (type, expr, convtype, flags)
           with a user-defined conversion sequence, then we direct-initialize
           the target with the temp (see [dcl.init]).  */
        ctor = build_user_type_conversion (type, ctor, flags);
-      if (ctor)
+      else
        ctor = build_method_call (NULL_TREE, 
                                  complete_ctor_identifier,
                                  build_tree_list (NULL_TREE, ctor),
index 92953b9bf156f5ac49a7f27ed97457d042ca125c..b208e653f2cc90a4668c53d1b3b06222b15572cf 100644 (file)
@@ -1340,6 +1340,11 @@ dump_function_name (t, flags)
 {
   tree name = DECL_NAME (t);
 
+  /* Don't let the user see __comp_ctor et al.  */
+  if (DECL_CONSTRUCTOR_P (t)
+      || DECL_DESTRUCTOR_P (t))
+    name = constructor_name (DECL_CONTEXT (t));
+
   if (DECL_DESTRUCTOR_P (t))
     {
       output_add_character (scratch_buffer, '~');
index 900ef3c6c6233d43b0e5c59f1c3ccd5fa72f24da..87d4195b3175da953e435beca08f0cfdad497a58 100644 (file)
@@ -5788,6 +5788,8 @@ tsubst_decl (t, args, type, in_decl)
            maybe_retrofit_in_chrg (r);
            if (DECL_CONSTRUCTOR_P (r))
              grok_ctor_properties (ctx, r);
+           if (PRIMARY_TEMPLATE_P (gen_tmpl))
+             clone_function_decl(r, /*update_method_vec_p=*/0);
          }
        else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
          grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r));
@@ -9280,15 +9282,6 @@ do_decl_instantiation (declspecs, declarator, storage)
     cp_error ("storage class `%D' applied to template instantiation",
              storage);
 
-  /* Under the new ABI, we need to make sure to instantiate all the
-     cloned versions of constructors or destructors.  */
-  if (flag_new_abi &&
-      (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (result) || 
-       DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (result)) &&
-      !(TREE_CHAIN (result) && 
-       DECL_CLONED_FUNCTION (TREE_CHAIN (result))))
-    clone_function_decl(result, /*update_method_vec_p=*/0);
-      
   SET_DECL_EXPLICIT_INSTANTIATION (result);
   mark_decl_instantiated (result, extern_p);
   repo_template_instantiated (result, extern_p);
index 99fe25554462866d1c467294e5fd64ed5c23ddff..fc775c4f0790d4dd8ff3e380ad66bf9c6a5050f6 100644 (file)
@@ -11,8 +11,8 @@
 class A
 {
 public:
-    A(int j) { i = j; }
-    A(A& a) { i = a.i; }
+    A(int j) { i = j; }                // ERROR - candidate
+    A(A& a) { i = a.i; }       // ERROR - candidate
     operator int() { return i; }
 
     void assign(int v) { i = v; }
@@ -38,10 +38,10 @@ B::run()
     // Replacing above with "switch (int(in))" removes the error.
     {
     case 0:
-        out = 1;
+        out = 1;               // ERROR - no usable copy ctor
         break;
     default:
-        out = 0;
+        out = 0;               // ERROR - no usable copy ctor
         break;
     }
 }
index 9af201011713d2a0ae29485906e6ce31375f530c..9e5250e43de0f5297db6e51668d9b8f20223d559 100644 (file)
@@ -4,7 +4,7 @@ int count;
 
 class A {
   A();
-  A(const A&);
+  A(const A&);                 // ERROR - referenced below
 public:
   A(int) { ++count; }
   ~A() { --count; }
@@ -14,7 +14,7 @@ public:
 int main() {
   {
     A a (1);
-    if (a == 2 && a == 1)
+    if (a == 2 && a == 1)      // ERROR - private copy ctor
       ;
   }
   return count;
index 0783f77dffe04ab24294c283995d257df00003cf..9cbd2dfe7a80b83ddad4cbaca66f456782876025 100644 (file)
@@ -4,7 +4,7 @@ int count;
 
 class A {
   A();
-  A(const A&);
+  A(const A&);                 // ERROR - referenced below
 public:
   A(int) { ++count; }
   ~A() { --count; }
@@ -14,7 +14,7 @@ public:
 int main() {
   {
     A a (1);
-    if (a == 2 || a == 1)
+    if (a == 2 || a == 1)      // ERROR - private copy ctor
       ;
   }
   return count;