OSDN Git Service

PR c++/43787
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index 837a65d..0ba0994 100644 (file)
@@ -144,7 +144,7 @@ static tree build_java_interface_fn_ref (tree, tree);
 static tree convert_like_real (conversion *, tree, tree, int, int, bool,
                               bool, tsubst_flags_t);
 static void op_error (enum tree_code, enum tree_code, tree, tree,
-                     tree, const char *);
+                     tree, bool);
 static VEC(tree,gc) *resolve_args (VEC(tree,gc) *);
 static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
 static void print_z_candidate (const char *, struct z_candidate *);
@@ -626,23 +626,27 @@ build_aggr_conv (tree type, tree ctor, int flags)
 {
   unsigned HOST_WIDE_INT i = 0;
   conversion *c;
-  tree field = TYPE_FIELDS (type);
+  tree field = next_initializable_field (TYPE_FIELDS (type));
 
-  for (; field; field = TREE_CHAIN (field), ++i)
+  for (; field; field = next_initializable_field (TREE_CHAIN (field)))
     {
-      if (TREE_CODE (field) != FIELD_DECL)
-       continue;
       if (i < CONSTRUCTOR_NELTS (ctor))
        {
          constructor_elt *ce = CONSTRUCTOR_ELT (ctor, i);
          if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (ce->value),
                                ce->value, flags))
            return NULL;
+         ++i;
+         if (TREE_CODE (type) == UNION_TYPE)
+           break;
        }
       else if (build_value_init (TREE_TYPE (field)) == error_mark_node)
        return NULL;
     }
 
+  if (i < CONSTRUCTOR_NELTS (ctor))
+    return NULL;
+
   c = alloc_conversion (ck_aggr);
   c->type = type;
   c->rank = cr_exact;
@@ -1009,7 +1013,7 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
   struct z_candidate *cand;
   bool any_viable_p;
 
-  conversions = lookup_conversions (s);
+  conversions = lookup_conversions (s, /*lookup_template_convs_p=*/true);
   if (!conversions)
     return NULL;
 
@@ -2259,6 +2263,8 @@ type_decays_to (tree type)
     return build_pointer_type (TREE_TYPE (type));
   if (TREE_CODE (type) == FUNCTION_TYPE)
     return build_pointer_type (type);
+  if (!MAYBE_CLASS_TYPE_P (type))
+    type = cv_unqualified (type);
   return type;
 }
 
@@ -2362,7 +2368,8 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
          if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR)
            return;
 
-         convs = lookup_conversions (argtypes[i]);
+         convs = lookup_conversions (argtypes[i],
+                                     /*lookup_template_convs_p=*/false);
 
          if (code == COND_EXPR)
            {
@@ -2730,6 +2737,7 @@ print_z_candidates (struct z_candidate *candidates)
   const char *str;
   struct z_candidate *cand1;
   struct z_candidate **cand2;
+  char *spaces;
 
   if (!candidates)
     return;
@@ -2770,25 +2778,14 @@ print_z_candidates (struct z_candidate *candidates)
        }
     }
 
-  str = _("candidates are:");
-  print_z_candidate (str, candidates);
-  if (candidates->next)
+  str = candidates->next ? _("candidates are:") :  _("candidate is:");
+  spaces = NULL;
+  for (; candidates; candidates = candidates->next)
     {
-      /* Indent successive candidates by the width of the translation
-        of the above string.  */
-      size_t len = gcc_gettext_width (str) + 1;
-      char *spaces = (char *) alloca (len);
-      memset (spaces, ' ', len-1);
-      spaces[len - 1] = '\0';
-
-      candidates = candidates->next;
-      do
-       {
-         print_z_candidate (spaces, candidates);
-         candidates = candidates->next;
-       }
-      while (candidates);
+      print_z_candidate (spaces ? spaces : str, candidates);
+      spaces = spaces ? spaces : get_spaces (str);
     }
+  free (spaces);
 }
 
 /* USER_SEQ is a user-defined conversion sequence, beginning with a
@@ -2861,7 +2858,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
             reference to it)...  */
        }
       else
-       conv_fns = lookup_conversions (fromtype);
+       conv_fns = lookup_conversions (fromtype,
+                                      /*lookup_template_convs_p=*/true);
     }
 
   candidates = 0;
@@ -2952,16 +2950,11 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
       for (fns = TREE_VALUE (conv_fns); fns; fns = OVL_NEXT (fns))
        {
          tree fn = OVL_CURRENT (fns);
-         tree first = first_arg;
 
          if (DECL_NONCONVERTING_P (fn)
              && (flags & LOOKUP_ONLYCONVERTING))
            continue;
 
-         /* Lambdas have a static conversion op.  */
-         if (DECL_STATIC_FUNCTION_P (fn))
-           first = NULL_TREE;
-
          /* [over.match.funcs] For conversion functions, the function
             is considered to be a member of the class of the implicit
             object argument for the purpose of defining the type of
@@ -2972,14 +2965,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            cand = add_template_candidate (&candidates, fn, fromtype,
                                           NULL_TREE,
-                                          first, NULL, totype,
+                                          first_arg, NULL, totype,
                                           TYPE_BINFO (fromtype),
                                           conversion_path,
                                           flags,
                                           DEDUCE_CONV);
          else
            cand = add_function_candidate (&candidates, fn, fromtype,
-                                          first, NULL,
+                                          first_arg, NULL,
                                           TYPE_BINFO (fromtype),
                                           conversion_path,
                                           flags);
@@ -3387,29 +3380,20 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
        {
          tree fn = OVL_CURRENT (fns);
 
-         tree lfirst = first_mem_arg;
-         if (DECL_STATIC_FUNCTION_P (fn))
-           lfirst = NULL_TREE;
-
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            add_template_candidate (&candidates, fn, base, NULL_TREE,
-                                   lfirst, *args, NULL_TREE,
+                                   first_mem_arg, *args, NULL_TREE,
                                    TYPE_BINFO (type),
                                    TYPE_BINFO (type),
                                    LOOKUP_NORMAL, DEDUCE_CALL);
          else
            add_function_candidate
-             (&candidates, fn, base, lfirst, *args, TYPE_BINFO (type),
+             (&candidates, fn, base, first_mem_arg, *args, TYPE_BINFO (type),
               TYPE_BINFO (type), LOOKUP_NORMAL);
        }
     }
 
-  /* Rather than mess with handling static conversion ops here, just don't
-     look at conversions in lambdas.  */
-  if (LAMBDA_TYPE_P (type))
-    convs = NULL_TREE;
-  else
-    convs = lookup_conversions (type);
+  convs = lookup_conversions (type, /*lookup_template_convs_p=*/true);
 
   for (; convs; convs = TREE_CHAIN (convs))
     {
@@ -3489,7 +3473,7 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
 
 static void
 op_error (enum tree_code code, enum tree_code code2,
-         tree arg1, tree arg2, tree arg3, const char *problem)
+         tree arg1, tree arg2, tree arg3, bool match)
 {
   const char *opname;
 
@@ -3501,31 +3485,58 @@ op_error (enum tree_code code, enum tree_code code2,
   switch (code)
     {
     case COND_EXPR:
-      error ("%s for ternary %<operator?:%> in %<%E ? %E : %E%>",
-            problem, arg1, arg2, arg3);
+      if (match)
+        error ("ambiguous overload for ternary %<operator?:%> "
+               "in %<%E ? %E : %E%>", arg1, arg2, arg3);
+      else
+        error ("no match for ternary %<operator?:%> "
+               "in %<%E ? %E : %E%>", arg1, arg2, arg3);
       break;
 
     case POSTINCREMENT_EXPR:
     case POSTDECREMENT_EXPR:
-      error ("%s for %<operator%s%> in %<%E%s%>", problem, opname, arg1, opname);
+      if (match)
+        error ("ambiguous overload for %<operator%s%> in %<%E%s%>",
+               opname, arg1, opname);
+      else
+        error ("no match for %<operator%s%> in %<%E%s%>", 
+               opname, arg1, opname);
       break;
 
     case ARRAY_REF:
-      error ("%s for %<operator[]%> in %<%E[%E]%>", problem, arg1, arg2);
+      if (match)
+        error ("ambiguous overload for %<operator[]%> in %<%E[%E]%>", 
+               arg1, arg2);
+      else
+        error ("no match for %<operator[]%> in %<%E[%E]%>", 
+               arg1, arg2);
       break;
 
     case REALPART_EXPR:
     case IMAGPART_EXPR:
-      error ("%s for %qs in %<%s %E%>", problem, opname, opname, arg1);
+      if (match)
+        error ("ambiguous overload for %qs in %<%s %E%>", 
+               opname, opname, arg1);
+      else
+        error ("no match for %qs in %<%s %E%>",
+               opname, opname, arg1);
       break;
 
     default:
       if (arg2)
-       error ("%s for %<operator%s%> in %<%E %s %E%>",
-              problem, opname, arg1, opname, arg2);
+        if (match)
+          error ("ambiguous overload for %<operator%s%> in %<%E %s %E%>",
+                  opname, arg1, opname, arg2);
+        else
+          error ("no match for %<operator%s%> in %<%E %s %E%>",
+                 opname, arg1, opname, arg2);
       else
-       error ("%s for %<operator%s%> in %<%s%E%>",
-              problem, opname, opname, arg1);
+        if (match)
+          error ("ambiguous overload for %<operator%s%> in %<%s%E%>",
+                 opname, opname, arg1);
+        else
+          error ("no match for %<operator%s%> in %<%s%E%>",
+                 opname, opname, arg1);
       break;
     }
 }
@@ -3852,7 +3863,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
        {
           if (complain & tf_error)
             {
-              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
+              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
               print_z_candidates (candidates);
             }
          return error_mark_node;
@@ -3862,7 +3873,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
        {
           if (complain & tf_error)
             {
-              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
+              op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
               print_z_candidates (candidates);
             }
          return error_mark_node;
@@ -4330,7 +4341,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
                  {
                    /* ... Otherwise, report the more generic
                       "no matching operator found" error */
-                   op_error (code, code2, arg1, arg2, arg3, "no match");
+                   op_error (code, code2, arg1, arg2, arg3, FALSE);
                    print_z_candidates (candidates);
                  }
            }
@@ -4345,7 +4356,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
        {
          if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
            {
-             op_error (code, code2, arg1, arg2, arg3, "ambiguous overload");
+             op_error (code, code2, arg1, arg2, arg3, TRUE);
              print_z_candidates (candidates);
            }
          result = error_mark_node;
@@ -4447,7 +4458,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
       return cp_build_modify_expr (arg1, code2, arg2, complain);
 
     case INDIRECT_REF:
-      return cp_build_indirect_ref (arg1, "unary *", complain);
+      return cp_build_indirect_ref (arg1, RO_UNARY_STAR, complain);
 
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
@@ -4492,7 +4503,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
       return build_array_ref (input_location, arg1, arg2);
 
     case MEMBER_REF:
-      return build_m_component_ref (cp_build_indirect_ref (arg1, NULL, 
+      return build_m_component_ref (cp_build_indirect_ref (arg1, RO_NULL, 
                                                            complain), 
                                     arg2);
 
@@ -4785,17 +4796,19 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
   if (expr == null_node && TREE_CODE (t) != BOOLEAN_TYPE && ARITHMETIC_TYPE_P (t))
     {
       if (fn)
-       warning (OPT_Wconversion, "passing NULL to non-pointer argument %P of %qD",
-                argnum, fn);
+       warning_at (input_location, OPT_Wconversion_null,
+                   "passing NULL to non-pointer argument %P of %qD",
+                   argnum, fn);
       else
-       warning (OPT_Wconversion, "converting to non-pointer type %qT from NULL", t);
+       warning_at (input_location, OPT_Wconversion_null,
+                   "converting to non-pointer type %qT from NULL", t);
     }
 
   /* Issue warnings if "false" is converted to a NULL pointer */
   else if (expr == boolean_false_node && fn && POINTER_TYPE_P (t))
-    warning (OPT_Wconversion,
-            "converting %<false%> to pointer type for argument %P of %qD",
-            argnum, fn);
+    warning_at (input_location, OPT_Wconversion_null,
+               "converting %<false%> to pointer type for argument %P of %qD",
+               argnum, fn);
 }
 
 /* Perform the conversions in CONVS on the expression EXPR.  FN and
@@ -4934,6 +4947,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
         }
       return expr;
     case ck_ambig:
+      if (!(complain & tf_error))
+       return error_mark_node;
       /* Call build_user_type_conversion again for the error.  */
       return build_user_type_conversion
        (totype, convs->u.expr, LOOKUP_NORMAL);
@@ -4994,7 +5009,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
   switch (convs->kind)
     {
     case ck_rvalue:
-      expr = convert_bitfield_to_declared_type (expr);
+      expr = decay_conversion (expr);
       if (! MAYBE_CLASS_TYPE_P (totype))
        return expr;
       /* Else fall through.  */
@@ -5006,8 +5021,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
          /* Build an expression for `*((base*) &expr)'.  */
          expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain);
          expr = convert_to_base (expr, build_pointer_type (totype),
-                                 !c_cast_p, /*nonnull=*/true);
-         expr = cp_build_indirect_ref (expr, "implicit conversion", complain);
+                                 !c_cast_p, /*nonnull=*/true, complain);
+         expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain);
          return expr;
        }
 
@@ -5129,7 +5144,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
     case ck_ptr:
       if (convs->base_p)
        expr = convert_to_base (expr, totype, !c_cast_p,
-                               /*nonnull=*/false);
+                               /*nonnull=*/false, complain);
       return build_nop (totype, expr);
 
     case ck_pmem:
@@ -5225,7 +5240,7 @@ build_x_va_arg (tree expr, tree type)
       error ("cannot receive objects of non-trivially-copyable type %q#T "
             "through %<...%>; ", type);
       expr = convert (build_pointer_type (type1), null_node);
-      expr = cp_build_indirect_ref (expr, NULL, tf_warning_or_error);
+      expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error);
       return expr;
     }
 
@@ -5646,8 +5661,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
          tree tmpl = TI_TEMPLATE (cand->template_decl);
          tree realparm = chain_index (j, DECL_ARGUMENTS (cand->fn));
          tree patparm = get_pattern_parm (realparm, tmpl);
+         tree pattype = TREE_TYPE (patparm);
+         if (PACK_EXPANSION_P (pattype))
+           pattype = PACK_EXPANSION_PATTERN (pattype);
+         pattype = non_reference (pattype);
 
-         if (!is_std_init_list (non_reference (TREE_TYPE (patparm))))
+         if (!is_std_init_list (pattype))
            {
              pedwarn (input_location, 0, "deducing %qT as %qT",
                       non_reference (TREE_TYPE (patparm)),
@@ -5722,7 +5741,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       if (targ)
        arg = targ;
       else
-       arg = cp_build_indirect_ref (arg, 0, complain);
+       arg = cp_build_indirect_ref (arg, RO_NULL, complain);
 
       if (TREE_CODE (arg) == TARGET_EXPR
          && TARGET_EXPR_LIST_INIT_P (arg))
@@ -5757,7 +5776,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
               || (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))
                   && !move_fn_p (fn)))
        {
-         tree to = stabilize_reference (cp_build_indirect_ref (fa, 0,
+         tree to = stabilize_reference (cp_build_indirect_ref (fa, RO_NULL,
                                                                complain));
 
          val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
@@ -5769,14 +5788,22 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
           && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CONTEXT (fn)))
     {
       tree to = stabilize_reference
-       (cp_build_indirect_ref (argarray[0], 0, complain));
+       (cp_build_indirect_ref (argarray[0], RO_NULL, complain));
       tree type = TREE_TYPE (to);
       tree as_base = CLASSTYPE_AS_BASE (type);
       tree arg = argarray[1];
 
-      if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
+      if (is_really_empty_class (type))
        {
-         arg = cp_build_indirect_ref (arg, 0, complain);
+         /* Avoid copying empty classes.  */
+         val = build2 (COMPOUND_EXPR, void_type_node, to, arg);
+         TREE_NO_WARNING (val) = 1;
+         val = build2 (COMPOUND_EXPR, type, val, to);
+         TREE_NO_WARNING (val) = 1;
+       }
+      else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
+       {
+         arg = cp_build_indirect_ref (arg, RO_NULL, complain);
          val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
        }
       else
@@ -5809,7 +5836,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
          t = convert (TREE_TYPE (arg0), t);
          if (test)
            t = build3 (COND_EXPR, TREE_TYPE (t), test, arg0, t);
-         val = cp_build_indirect_ref (t, 0, complain);
+         val = cp_build_indirect_ref (t, RO_NULL, complain);
           TREE_NO_WARNING (val) = 1;
        }
 
@@ -5917,7 +5944,7 @@ build_java_interface_fn_ref (tree fn, tree instance)
 
   /* Look up the pointer to the runtime java.lang.Class object for `instance'.
      This is the first entry in the vtable.  */
-  klass_ref = build_vtbl_ref (cp_build_indirect_ref (instance, 0
+  klass_ref = build_vtbl_ref (cp_build_indirect_ref (instance, RO_NULL
                                                      tf_warning_or_error),
                              integer_zero_node);
 
@@ -6180,7 +6207,7 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
     *fn_p = NULL_TREE;
 
   if (error_operand_p (instance)
-      || error_operand_p (fns))
+      || !fns || error_operand_p (fns))
     return error_mark_node;
 
   if (!BASELINK_P (fns))
@@ -6222,6 +6249,24 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
        make_args_non_dependent (*args);
     }
 
+  user_args = args == NULL ? NULL : *args;
+  /* Under DR 147 A::A() is an invalid constructor call,
+     not a functional cast.  */
+  if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
+    {
+      if (! (complain & tf_error))
+       return error_mark_node;
+
+      permerror (input_location,
+                "cannot call constructor %<%T::%D%> directly",
+                basetype, name);
+      permerror (input_location, "  for a function-style cast, remove the "
+                "redundant %<::%D%>", name);
+      call = build_functional_cast (basetype, build_tree_list_vec (user_args),
+                                   complain);
+      return call;
+    }
+
   /* Figure out whether to skip the first argument for the error
      message we will display to users if an error occurs.  We don't
      want to display any compiler-generated arguments.  The "this"
@@ -6229,7 +6274,6 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
      pointer if this is a call to a base-class constructor or
      destructor.  */
   skip_first_for_error = false;
-  user_args = args == NULL ? NULL : *args;
   if (IDENTIFIER_CTOR_OR_DTOR_P (name))
     {
       /* Callers should explicitly indicate whether they want to construct
@@ -7530,7 +7574,7 @@ perform_direct_initialization_if_possible (tree type,
     expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
                              /*issue_conversion_warnings=*/false,
                              c_cast_p,
-                             tf_warning_or_error);
+                             complain);
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -7756,7 +7800,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup,
                expr = convert_to_base (expr,
                                        build_pointer_type (base_conv_type),
                                        /*check_access=*/true,
-                                       /*nonnull=*/true);
+                                       /*nonnull=*/true, complain);
              expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
            }
          else