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. */
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))
if (!expr)
return NULL;
- conversions = lookup_conversions (s, /*lookup_template_convs_p=*/true);
+ conversions = lookup_conversions (s);
if (!conversions)
return NULL;
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;
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)
{
reference to it)... */
}
else
- conv_fns = lookup_conversions (fromtype,
- /*lookup_template_convs_p=*/true);
+ conv_fns = lookup_conversions (fromtype);
}
candidates = 0;
LOOKUP_NORMAL, &candidates);
}
- convs = lookup_conversions (type, /*lookup_template_convs_p=*/true);
+ convs = lookup_conversions (type);
for (; convs; convs = TREE_CHAIN (convs))
{
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)
{
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);
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;
}
}
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));
{
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%>",