OSDN Git Service

Fix PR c++/42260 and ensure PR c++/45383 is fixed
[pf3gnuchains/gcc-fork.git] / gcc / cp / call.c
index a1c8682..0f016ca 100644 (file)
@@ -639,6 +639,29 @@ build_list_conv (tree type, tree ctor, int flags)
   return t;
 }
 
+/* Subroutine of build_aggr_conv: check whether CTOR, a braced-init-list,
+   is a valid aggregate initializer for array type ATYPE.  */
+
+static bool
+can_convert_array (tree atype, tree ctor, int flags)
+{
+  unsigned i;
+  tree elttype = TREE_TYPE (atype);
+  for (i = 0; i < CONSTRUCTOR_NELTS (ctor); ++i)
+    {
+      tree val = CONSTRUCTOR_ELT (ctor, i)->value;
+      bool ok;
+      if (TREE_CODE (elttype) == ARRAY_TYPE
+         && TREE_CODE (val) == CONSTRUCTOR)
+       ok = can_convert_array (elttype, val, flags);
+      else
+       ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags);
+      if (!ok)
+       return false;
+    }
+  return true;
+}
+
 /* Represent a conversion from CTOR, a braced-init-list, to TYPE, an
    aggregate class, if such a conversion is possible.  */
 
@@ -652,24 +675,31 @@ build_aggr_conv (tree type, tree ctor, int flags)
 
   for (; field; field = next_initializable_field (DECL_CHAIN (field)))
     {
+      tree ftype = TREE_TYPE (field);
+      tree val;
+      bool ok;
+
       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;
-       }
+       val = CONSTRUCTOR_ELT (ctor, i)->value;
       else
        {
          if (empty_ctor == NULL_TREE)
            empty_ctor = build_constructor (init_list_type_node, NULL);
-         if (!can_convert_arg (TREE_TYPE (field), TREE_TYPE (empty_ctor),
-                               empty_ctor, flags))
-           return NULL;
+         val = empty_ctor;
        }
+      ++i;
+
+      if (TREE_CODE (ftype) == ARRAY_TYPE
+         && TREE_CODE (val) == CONSTRUCTOR)
+       ok = can_convert_array (ftype, val, flags);
+      else
+       ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags);
+
+      if (!ok)
+       return NULL;
+
+      if (TREE_CODE (type) == UNION_TYPE)
+       break;
     }
 
   if (i < CONSTRUCTOR_NELTS (ctor))
@@ -1063,7 +1093,7 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
   if (!expr)
     return NULL;
 
-  conversions = lookup_conversions (s, /*lookup_template_convs_p=*/true);
+  conversions = lookup_conversions (s);
   if (!conversions)
     return NULL;
 
@@ -1992,6 +2022,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
 
     case INDIRECT_REF:
       if (TREE_CODE (type1) == POINTER_TYPE
+         && is_complete (TREE_TYPE (type1))
          && (TYPE_PTROB_P (type1)
              || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE))
        break;
@@ -2434,8 +2465,7 @@ 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],
-                                     /*lookup_template_convs_p=*/false);
+         convs = lookup_conversions (argtypes[i]);
 
          if (code == COND_EXPR)
            {
@@ -2998,8 +3028,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
             reference to it)...  */
        }
       else
-       conv_fns = lookup_conversions (fromtype,
-                                      /*lookup_template_convs_p=*/true);
+       conv_fns = lookup_conversions (fromtype);
     }
 
   candidates = 0;
@@ -3555,7 +3584,7 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
                      LOOKUP_NORMAL, &candidates);
     }
 
-  convs = lookup_conversions (type, /*lookup_template_convs_p=*/true);
+  convs = lookup_conversions (type);
 
   for (; convs; convs = TREE_CHAIN (convs))
     {
@@ -5260,6 +5289,10 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
           conversion (i.e. the second step of copy-initialization), so
           don't allow any more.  */
        flags |= LOOKUP_NO_CONVERSION;
+      if (TREE_CODE (expr) == TARGET_EXPR
+         && TARGET_EXPR_LIST_INIT_P (expr))
+       /* Copy-list-initialization doesn't actually involve a copy.  */
+       return expr;
       expr = build_temp (expr, totype, flags, &diag_kind, complain);
       if (diag_kind && fn)
        {
@@ -5793,15 +5826,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        access_fn = fn;
       if (flags & LOOKUP_SPECULATIVE)
        {
-         /* If we're checking for implicit delete, we don't want access
-            control errors.  */
-         if (!accessible_p (cand->access_path, access_fn, true))
-           {
-             /* Unless we're under maybe_explain_implicit_delete.  */
-             if (flags & LOOKUP_COMPLAIN)
-               enforce_access (cand->access_path, access_fn, fn);
-             return error_mark_node;
-           }
+         if (!speculative_access_check (cand->access_path, access_fn, fn,
+                                        !!(flags & LOOKUP_COMPLAIN)))
+           return error_mark_node;
        }
       else
        perform_or_defer_access_check (cand->access_path, access_fn, fn);
@@ -6025,15 +6052,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       else
        arg = cp_build_indirect_ref (arg, RO_NULL, complain);
 
-      if (TREE_CODE (arg) == TARGET_EXPR
-         && TARGET_EXPR_LIST_INIT_P (arg))
-       {
-         /* Copy-list-initialization doesn't require the constructor
-            to be defined.  */
-       }
       /* [class.copy]: the copy constructor is implicitly defined even if
         the implementation elided its use.  */
-      else if (!trivial)
+      if (!trivial || DECL_DELETED_FN (fn))
        {
          mark_used (fn);
          already_used = true;
@@ -6062,7 +6083,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        }
     }
   else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
-          && trivial_fn_p (fn))
+          && trivial_fn_p (fn)
+          && !DECL_DELETED_FN (fn))
     {
       tree to = stabilize_reference
        (cp_build_indirect_ref (argarray[0], RO_NULL, complain));
@@ -6616,7 +6638,7 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
     {
       if (complain & tf_error)
        {
-         if (!COMPLETE_TYPE_P (basetype))
+         if (!COMPLETE_OR_OPEN_TYPE_P (basetype))
            cxx_incomplete_type_error (instance_ptr, basetype);
          else if (optype)
            error ("no matching function for call to %<%T::operator %T(%A)%#V%>",