aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-04-24 16:25:15 +0000
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-04-24 16:25:15 +0000
commit66bbeb85a1afce21387728b2027a2ea00eada884 (patch)
treee6624c8acded44cfe59898448175ad6c47ed2150
parentc72aec62c2fc638ef7b5c258e53650395ed6564a (diff)
/cp
2012-04-24 Paolo Carlini <paolo.carlini@oracle.com> PR c++/52363 * call.c (tourney, perform_overload_resolution, build_operator_new_call, build_user_type_conversion_1, build_user_type_conversion, perform_overload_resolution, add_template_candidate, add_template_candidate_real, add_template_conv_candidate, add_builtin_candidates, add_builtin_candidate, build_builtin_candidate, add_conv_candidate, add_function_candidate, implicit_conversion, reference_binding, build_list_conv, conditional_conversion, add_candidates, can_convert_array, build_aggr_conv, build_array_conv, build_complex_conv, conditional_conversion): Add tsubst_flags_t parameter. (joust): Likewise, use it to handle SFINAE as if pedantic. (add_list_candidates, build_integral_nontype_arg_conv, perform_overload_resolution, build_new_function_call, build_operator_new_call, build_op_call_1, build_conditional_expr_1, build_new_op_1, convert_like_real, convert_arg_to_ellipsis, convert_default_arg, convert_for_arg_passing, build_over_call, build_new_method_call_1, can_convert_arg, can_convert_arg_bad, perform_implicit_conversion_flags, perform_direct_initialization_if_possible, initialize_reference): Adjust. * typeck.c (casts_away_constness, casts_away_constness_r): Add tsubst_flags_t parameter. (convert_arguments, check_for_casting_away_constness, build_static_cast_1, build_ptrmemfunc, convert_for_assignment): Adjust. * decl.c (reshape_init_r, check_default_argument): Likewise. * cp-gimplify.c (cxx_omp_clause_apply_fn): Likewise. * pt.c (convert_nontype_argument, check_non_deducible_conversion): Likewise. * init.c (build_new_1): Likewise. * cvt.c (convert_to_reference, ocp_convert, build_type_conversion, build_expr_type_conversion, ): Likewise. * search.c (check_final_overrider): Likewise. * cp-tree.h (build_user_type_conversion, build_operator_new_call, can_convert, can_convert_arg, can_convert_arg_bad, convert_default_arg, convert_arg_to_ellipsis, convert_for_arg_passing): Adjust declaration. /testsuite 2012-04-24 Paolo Carlini <paolo.carlini@oracle.com> PR c++/52363 * g++.dg/cpp0x/sfinae35.C: New. * g++.dg/cpp0x/sfinae36.C: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186774 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog44
-rw-r--r--gcc/cp/call.c379
-rw-r--r--gcc/cp/cp-gimplify.c5
-rw-r--r--gcc/cp/cp-tree.h21
-rw-r--r--gcc/cp/cvt.c20
-rw-r--r--gcc/cp/decl.c6
-rw-r--r--gcc/cp/init.c2
-rw-r--r--gcc/cp/pt.c7
-rw-r--r--gcc/cp/search.c6
-rw-r--r--gcc/cp/typeck.c41
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/sfinae35.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/sfinae36.C13
13 files changed, 360 insertions, 205 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 69c5916cfaf..86e44fc0fc6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,47 @@
+2012-04-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52363
+ * call.c (tourney, perform_overload_resolution,
+ build_operator_new_call, build_user_type_conversion_1,
+ build_user_type_conversion, perform_overload_resolution,
+ add_template_candidate, add_template_candidate_real,
+ add_template_conv_candidate, add_builtin_candidates,
+ add_builtin_candidate, build_builtin_candidate,
+ add_conv_candidate, add_function_candidate, implicit_conversion,
+ reference_binding, build_list_conv, conditional_conversion,
+ add_candidates, can_convert_array, build_aggr_conv,
+ build_array_conv, build_complex_conv, conditional_conversion):
+ Add tsubst_flags_t parameter.
+ (joust): Likewise, use it to handle SFINAE as if pedantic.
+ (add_list_candidates, build_integral_nontype_arg_conv,
+ perform_overload_resolution, build_new_function_call,
+ build_operator_new_call, build_op_call_1,
+ build_conditional_expr_1, build_new_op_1, convert_like_real,
+ convert_arg_to_ellipsis, convert_default_arg,
+ convert_for_arg_passing, build_over_call,
+ build_new_method_call_1, can_convert_arg, can_convert_arg_bad,
+ perform_implicit_conversion_flags,
+ perform_direct_initialization_if_possible,
+ initialize_reference): Adjust.
+ * typeck.c (casts_away_constness, casts_away_constness_r):
+ Add tsubst_flags_t parameter.
+ (convert_arguments, check_for_casting_away_constness,
+ build_static_cast_1, build_ptrmemfunc, convert_for_assignment):
+ Adjust.
+ * decl.c (reshape_init_r, check_default_argument): Likewise.
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Likewise.
+ * pt.c (convert_nontype_argument, check_non_deducible_conversion):
+ Likewise.
+ * init.c (build_new_1): Likewise.
+ * cvt.c (convert_to_reference, ocp_convert, build_type_conversion,
+ build_expr_type_conversion, ): Likewise.
+ * search.c (check_final_overrider): Likewise.
+ * cp-tree.h (build_user_type_conversion,
+ build_operator_new_call, can_convert, can_convert_arg,
+ can_convert_arg_bad, convert_default_arg,
+ convert_arg_to_ellipsis, convert_for_arg_passing):
+ Adjust declaration.
+
2012-04-22 Jan Hubicka <jh@suse.cz>
* decl2.c (maybe_make_one_only): Mark keyed COMDATs as USED so they
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 4223f6cb16e..f9a7f08b8d3 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -142,9 +142,10 @@ static struct obstack conversion_obstack;
static bool conversion_obstack_initialized;
struct rejection_reason;
-static struct z_candidate * tourney (struct z_candidate *);
+static struct z_candidate * tourney (struct z_candidate *, tsubst_flags_t);
static int equal_functions (tree, tree);
-static int joust (struct z_candidate *, struct z_candidate *, bool);
+static int joust (struct z_candidate *, struct z_candidate *, bool,
+ tsubst_flags_t);
static int compare_ics (conversion *, conversion *);
static tree build_over_call (struct z_candidate *, int, tsubst_flags_t);
static tree build_java_interface_fn_ref (tree, tree);
@@ -160,7 +161,8 @@ 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, bool);
-static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
+static struct z_candidate *build_user_type_conversion_1 (tree, tree, int,
+ tsubst_flags_t);
static void print_z_candidate (const char *, struct z_candidate *);
static void print_z_candidates (location_t, struct z_candidate *);
static tree build_this (tree);
@@ -168,34 +170,36 @@ static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
static bool any_strictly_viable (struct z_candidate *);
static struct z_candidate *add_template_candidate
(struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *,
- tree, tree, tree, int, unification_kind_t);
+ tree, tree, tree, int, unification_kind_t, tsubst_flags_t);
static struct z_candidate *add_template_candidate_real
(struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *,
- tree, tree, tree, int, tree, unification_kind_t);
+ tree, tree, tree, int, tree, unification_kind_t, tsubst_flags_t);
static struct z_candidate *add_template_conv_candidate
(struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
- tree, tree);
+ tree, tree, tsubst_flags_t);
static void add_builtin_candidates
(struct z_candidate **, enum tree_code, enum tree_code,
- tree, tree *, int);
+ tree, tree *, int, tsubst_flags_t);
static void add_builtin_candidate
(struct z_candidate **, enum tree_code, enum tree_code,
- tree, tree, tree, tree *, tree *, int);
+ tree, tree, tree, tree *, tree *, int, tsubst_flags_t);
static bool is_complete (tree);
static void build_builtin_candidate
(struct z_candidate **, tree, tree, tree, tree *, tree *,
- int);
+ int, tsubst_flags_t);
static struct z_candidate *add_conv_candidate
(struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
- tree);
+ tree, tsubst_flags_t);
static struct z_candidate *add_function_candidate
(struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
- tree, int);
-static conversion *implicit_conversion (tree, tree, tree, bool, int);
+ tree, int, tsubst_flags_t);
+static conversion *implicit_conversion (tree, tree, tree, bool, int,
+ tsubst_flags_t);
static conversion *standard_conversion (tree, tree, tree, bool, int);
-static conversion *reference_binding (tree, tree, tree, bool, int);
+static conversion *reference_binding (tree, tree, tree, bool, int,
+ tsubst_flags_t);
static conversion *build_conv (conversion_kind, tree, conversion *);
-static conversion *build_list_conv (tree, tree, int);
+static conversion *build_list_conv (tree, tree, int, tsubst_flags_t);
static conversion *next_conversion (conversion *);
static bool is_subseq (conversion *, conversion *);
static conversion *maybe_handle_ref_bind (conversion **);
@@ -208,11 +212,12 @@ static void add_warning (struct z_candidate *, struct z_candidate *);
static bool reference_compatible_p (tree, tree);
static conversion *direct_reference_binding (tree, conversion *);
static bool promoted_arithmetic_type_p (tree);
-static conversion *conditional_conversion (tree, tree);
+static conversion *conditional_conversion (tree, tree, tsubst_flags_t);
static char *name_as_c_string (tree, tree, bool *);
static tree prep_operand (tree);
static void add_candidates (tree, tree, const VEC(tree,gc) *, tree, tree, bool,
- tree, tree, int, struct z_candidate **);
+ tree, tree, int, struct z_candidate **,
+ tsubst_flags_t);
static conversion *merge_conversion_sequences (conversion *, conversion *);
static bool magic_varargs_p (tree);
static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t);
@@ -793,7 +798,7 @@ build_conv (conversion_kind code, tree type, conversion *from)
possible. */
static conversion *
-build_list_conv (tree type, tree ctor, int flags)
+build_list_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
{
tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (type), 0);
unsigned len = CONSTRUCTOR_NELTS (ctor);
@@ -812,7 +817,7 @@ build_list_conv (tree type, tree ctor, int flags)
{
conversion *sub
= implicit_conversion (elttype, TREE_TYPE (val), val,
- false, flags);
+ false, flags, complain);
if (sub == NULL)
return NULL;
@@ -857,7 +862,7 @@ next_conversion (conversion *conv)
is a valid aggregate initializer for array type ATYPE. */
static bool
-can_convert_array (tree atype, tree ctor, int flags)
+can_convert_array (tree atype, tree ctor, int flags, tsubst_flags_t complain)
{
unsigned i;
tree elttype = TREE_TYPE (atype);
@@ -867,9 +872,10 @@ can_convert_array (tree atype, tree ctor, int flags)
bool ok;
if (TREE_CODE (elttype) == ARRAY_TYPE
&& TREE_CODE (val) == CONSTRUCTOR)
- ok = can_convert_array (elttype, val, flags);
+ ok = can_convert_array (elttype, val, flags, complain);
else
- ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags);
+ ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags,
+ complain);
if (!ok)
return false;
}
@@ -880,7 +886,7 @@ can_convert_array (tree atype, tree ctor, int flags)
aggregate class, if such a conversion is possible. */
static conversion *
-build_aggr_conv (tree type, tree ctor, int flags)
+build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
{
unsigned HOST_WIDE_INT i = 0;
conversion *c;
@@ -909,9 +915,10 @@ build_aggr_conv (tree type, tree ctor, int flags)
if (TREE_CODE (ftype) == ARRAY_TYPE
&& TREE_CODE (val) == CONSTRUCTOR)
- ok = can_convert_array (ftype, val, flags);
+ ok = can_convert_array (ftype, val, flags, complain);
else
- ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags);
+ ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags,
+ complain);
if (!ok)
return NULL;
@@ -935,7 +942,7 @@ build_aggr_conv (tree type, tree ctor, int flags)
array type, if such a conversion is possible. */
static conversion *
-build_array_conv (tree type, tree ctor, int flags)
+build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
{
conversion *c;
unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor);
@@ -957,7 +964,7 @@ build_array_conv (tree type, tree ctor, int flags)
{
conversion *sub
= implicit_conversion (elttype, TREE_TYPE (val), val,
- false, flags);
+ false, flags, complain);
if (sub == NULL)
return NULL;
@@ -982,7 +989,8 @@ build_array_conv (tree type, tree ctor, int flags)
complex type, if such a conversion is possible. */
static conversion *
-build_complex_conv (tree type, tree ctor, int flags)
+build_complex_conv (tree type, tree ctor, int flags,
+ tsubst_flags_t complain)
{
conversion *c;
unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor);
@@ -1000,7 +1008,7 @@ build_complex_conv (tree type, tree ctor, int flags)
{
conversion *sub
= implicit_conversion (elttype, TREE_TYPE (val), val,
- false, flags);
+ false, flags, complain);
if (sub == NULL)
return NULL;
@@ -1438,7 +1446,8 @@ direct_reference_binding (tree type, conversion *conv)
conversion is coming from a C-style cast. */
static conversion *
-reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
+reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
+ tsubst_flags_t complain)
{
conversion *conv = NULL;
tree to = TREE_TYPE (rto);
@@ -1461,7 +1470,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
{
maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
conv = implicit_conversion (to, from, expr, c_cast_p,
- flags);
+ flags, complain);
if (!CLASS_TYPE_P (to)
&& CONSTRUCTOR_NELTS (expr) == 1)
{
@@ -1597,7 +1606,8 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
the reference is bound to the lvalue result of the conversion
in the second case. */
- z_candidate *cand = build_user_type_conversion_1 (rto, expr, flags);
+ z_candidate *cand = build_user_type_conversion_1 (rto, expr, flags,
+ complain);
if (cand)
return cand->second_conv;
}
@@ -1652,7 +1662,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
if (!conv)
conv = implicit_conversion (to, from, expr, c_cast_p,
- flags);
+ flags, complain);
if (!conv)
return NULL;
@@ -1672,7 +1682,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
static conversion *
implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
- int flags)
+ int flags, tsubst_flags_t complain)
{
conversion *conv;
@@ -1687,7 +1697,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
|LOOKUP_NO_NARROWING|LOOKUP_PROTECT);
if (TREE_CODE (to) == REFERENCE_TYPE)
- conv = reference_binding (to, from, expr, c_cast_p, flags);
+ conv = reference_binding (to, from, expr, c_cast_p, flags, complain);
else
conv = standard_conversion (to, from, expr, c_cast_p, flags);
@@ -1697,12 +1707,12 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
{
if (is_std_init_list (to))
- return build_list_conv (to, expr, flags);
+ return build_list_conv (to, expr, flags, complain);
/* As an extension, allow list-initialization of _Complex. */
if (TREE_CODE (to) == COMPLEX_TYPE)
{
- conv = build_complex_conv (to, expr, flags);
+ conv = build_complex_conv (to, expr, flags, complain);
if (conv)
return conv;
}
@@ -1722,7 +1732,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
elt = error_mark_node;
conv = implicit_conversion (to, TREE_TYPE (elt), elt,
- c_cast_p, flags);
+ c_cast_p, flags, complain);
if (conv)
{
conv->check_narrowing = true;
@@ -1733,7 +1743,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
}
}
else if (TREE_CODE (to) == ARRAY_TYPE)
- return build_array_conv (to, expr, flags);
+ return build_array_conv (to, expr, flags, complain);
}
if (expr != NULL_TREE
@@ -1746,9 +1756,9 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
if (CLASS_TYPE_P (to)
&& BRACE_ENCLOSED_INITIALIZER_P (expr)
&& !CLASSTYPE_NON_AGGREGATE (complete_type (to)))
- return build_aggr_conv (to, expr, flags);
+ return build_aggr_conv (to, expr, flags, complain);
- cand = build_user_type_conversion_1 (to, expr, flags);
+ cand = build_user_type_conversion_1 (to, expr, flags, complain);
if (cand)
conv = cand->second_conv;
@@ -1818,7 +1828,8 @@ static struct z_candidate *
add_function_candidate (struct z_candidate **candidates,
tree fn, tree ctype, tree first_arg,
const VEC(tree,gc) *args, tree access_path,
- tree conversion_path, int flags)
+ tree conversion_path, int flags,
+ tsubst_flags_t complain)
{
tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
int i, len;
@@ -1977,7 +1988,7 @@ add_function_candidate (struct z_candidate **candidates,
lflags |= LOOKUP_ONLYCONVERTING;
t = implicit_conversion (parmtype, argtype, arg,
- /*c_cast_p=*/false, lflags);
+ /*c_cast_p=*/false, lflags, complain);
to_type = parmtype;
}
else
@@ -2025,7 +2036,8 @@ add_function_candidate (struct z_candidate **candidates,
static struct z_candidate *
add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
tree first_arg, const VEC(tree,gc) *arglist,
- tree access_path, tree conversion_path)
+ tree access_path, tree conversion_path,
+ tsubst_flags_t complain)
{
tree totype = TREE_TYPE (TREE_TYPE (fn));
int i, len, viable, flags;
@@ -2065,7 +2077,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
if (i == 0)
{
t = implicit_conversion (totype, argtype, arg, /*c_cast_p=*/false,
- flags);
+ flags, complain);
convert_type = totype;
}
else if (parmnode == void_list_node)
@@ -2073,7 +2085,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
else if (parmnode)
{
t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg,
- /*c_cast_p=*/false, flags);
+ /*c_cast_p=*/false, flags, complain);
convert_type = TREE_VALUE (parmnode);
}
else
@@ -2115,7 +2127,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
static void
build_builtin_candidate (struct z_candidate **candidates, tree fnname,
tree type1, tree type2, tree *args, tree *argtypes,
- int flags)
+ int flags, tsubst_flags_t complain)
{
conversion *t;
conversion **convs;
@@ -2144,18 +2156,20 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
break;
t = implicit_conversion (types[i], argtypes[i], args[i],
- /*c_cast_p=*/false, flags);
+ /*c_cast_p=*/false, flags, complain);
if (! t)
{
viable = 0;
/* We need something for printing the candidate. */
t = build_identity_conv (types[i], NULL_TREE);
- reason = arg_conversion_rejection (NULL_TREE, i, argtypes[i], types[i]);
+ reason = arg_conversion_rejection (NULL_TREE, i, argtypes[i],
+ types[i]);
}
else if (t->bad_p)
{
viable = 0;
- reason = bad_arg_conversion_rejection (NULL_TREE, i, argtypes[i], types[i]);
+ reason = bad_arg_conversion_rejection (NULL_TREE, i, argtypes[i],
+ types[i]);
}
convs[i] = t;
}
@@ -2166,7 +2180,8 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
convs[2] = convs[1];
convs[1] = convs[0];
t = implicit_conversion (boolean_type_node, argtypes[2], args[2],
- /*c_cast_p=*/false, flags);
+ /*c_cast_p=*/false, flags,
+ complain);
if (t)
convs[0] = t;
else
@@ -2220,7 +2235,8 @@ promoted_arithmetic_type_p (tree type)
static void
add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
enum tree_code code2, tree fnname, tree type1,
- tree type2, tree *args, tree *argtypes, int flags)
+ tree type2, tree *args, tree *argtypes, int flags,
+ tsubst_flags_t complain)
{
switch (code)
{
@@ -2614,20 +2630,21 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
if (cptype != error_mark_node)
{
build_builtin_candidate
- (candidates, fnname, cptype, cptype, args, argtypes, flags);
+ (candidates, fnname, cptype, cptype, args, argtypes,
+ flags, complain);
return;
}
}
build_builtin_candidate
- (candidates, fnname, type1, type1, args, argtypes, flags);
+ (candidates, fnname, type1, type1, args, argtypes, flags, complain);
build_builtin_candidate
- (candidates, fnname, type2, type2, args, argtypes, flags);
+ (candidates, fnname, type2, type2, args, argtypes, flags, complain);
return;
}
build_builtin_candidate
- (candidates, fnname, type1, type2, args, argtypes, flags);
+ (candidates, fnname, type1, type2, args, argtypes, flags, complain);
}
tree
@@ -2656,7 +2673,7 @@ type_decays_to (tree type)
static void
add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
enum tree_code code2, tree fnname, tree *args,
- int flags)
+ int flags, tsubst_flags_t complain)
{
int ref1, i;
int enum_p = 0;
@@ -2697,14 +2714,14 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
case TRUTH_NOT_EXPR:
build_builtin_candidate
(candidates, fnname, boolean_type_node,
- NULL_TREE, args, argtypes, flags);
+ NULL_TREE, args, argtypes, flags, complain);
return;
case TRUTH_ORIF_EXPR:
case TRUTH_ANDIF_EXPR:
build_builtin_candidate
(candidates, fnname, boolean_type_node,
- boolean_type_node, args, argtypes, flags);
+ boolean_type_node, args, argtypes, flags, complain);
return;
case ADDR_EXPR:
@@ -2810,11 +2827,11 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
FOR_EACH_VEC_ELT_REVERSE (tree, types[1], jx, u)
add_builtin_candidate
(candidates, code, code2, fnname, t,
- u, args, argtypes, flags);
+ u, args, argtypes, flags, complain);
else
add_builtin_candidate
(candidates, code, code2, fnname, t,
- NULL_TREE, args, argtypes, flags);
+ NULL_TREE, args, argtypes, flags, complain);
}
release_tree_vector (types[0]);
@@ -2837,7 +2854,8 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
tree ctype, tree explicit_targs, tree first_arg,
const VEC(tree,gc) *arglist, tree return_type,
tree access_path, tree conversion_path,
- int flags, tree obj, unification_kind_t strict)
+ int flags, tree obj, unification_kind_t strict,
+ tsubst_flags_t complain)
{
int ntparms = DECL_NTPARMS (tmpl);
tree targs = make_tree_vec (ntparms);
@@ -2958,11 +2976,11 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
if (obj != NULL_TREE)
/* Aha, this is a conversion function. */
cand = add_conv_candidate (candidates, fn, obj, first_arg, arglist,
- access_path, conversion_path);
+ access_path, conversion_path, complain);
else
cand = add_function_candidate (candidates, fn, ctype,
first_arg, arglist, access_path,
- conversion_path, flags);
+ conversion_path, flags, complain);
if (DECL_TI_TEMPLATE (fn) != tmpl)
/* This situation can occur if a member template of a template
class is specialized. Then, instantiate_template might return
@@ -2998,13 +3016,13 @@ add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype,
tree explicit_targs, tree first_arg,
const VEC(tree,gc) *arglist, tree return_type,
tree access_path, tree conversion_path, int flags,
- unification_kind_t strict)
+ unification_kind_t strict, tsubst_flags_t complain)
{
return
add_template_candidate_real (candidates, tmpl, ctype,
explicit_targs, first_arg, arglist,
return_type, access_path, conversion_path,
- flags, NULL_TREE, strict);
+ flags, NULL_TREE, strict, complain);
}
@@ -3013,12 +3031,13 @@ add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
tree obj, tree first_arg,
const VEC(tree,gc) *arglist,
tree return_type, tree access_path,
- tree conversion_path)
+ tree conversion_path, tsubst_flags_t complain)
{
return
add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
first_arg, arglist, return_type, access_path,
- conversion_path, 0, obj, DEDUCE_CONV);
+ conversion_path, 0, obj, DEDUCE_CONV,
+ complain);
}
/* The CANDS are the set of candidates that were considered for
@@ -3341,7 +3360,8 @@ add_list_candidates (tree fns, tree first_arg,
tree explicit_targs, bool template_only,
tree conversion_path, tree access_path,
int flags,
- struct z_candidate **candidates)
+ struct z_candidate **candidates,
+ tsubst_flags_t complain)
{
VEC(tree,gc) *args;
@@ -3365,7 +3385,7 @@ add_list_candidates (tree fns, tree first_arg,
args = make_tree_vector_single (init_list);
add_candidates (fns, first_arg, args, NULL_TREE,
explicit_targs, template_only, conversion_path,
- access_path, flags, candidates);
+ access_path, flags, candidates, complain);
if (any_strictly_viable (*candidates))
return;
}
@@ -3379,7 +3399,7 @@ add_list_candidates (tree fns, tree first_arg,
add_candidates (fns, first_arg, args, NULL_TREE,
explicit_targs, template_only, conversion_path,
- access_path, flags, candidates);
+ access_path, flags, candidates, complain);
}
/* Returns the best overload candidate to perform the requested
@@ -3389,7 +3409,8 @@ add_list_candidates (tree fns, tree first_arg,
per [dcl.init.ref], so we ignore temporary bindings. */
static struct z_candidate *
-build_user_type_conversion_1 (tree totype, tree expr, int flags)
+build_user_type_conversion_1 (tree totype, tree expr, int flags,
+ tsubst_flags_t complain)
{
struct z_candidate *candidates, *cand;
tree fromtype;
@@ -3460,14 +3481,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
/* List-initialization. */
add_list_candidates (ctors, first_arg, expr, totype, NULL_TREE,
false, TYPE_BINFO (totype), TYPE_BINFO (totype),
- ctorflags, &candidates);
+ ctorflags, &candidates, complain);
}
else
{
args = make_tree_vector_single (expr);
add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false,
TYPE_BINFO (totype), TYPE_BINFO (totype),
- ctorflags, &candidates);
+ ctorflags, &candidates, complain);
}
for (cand = candidates; cand; cand = cand->next)
@@ -3508,7 +3529,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
add_candidates (TREE_VALUE (conv_fns), first_arg, NULL, totype,
NULL_TREE, false,
conversion_path, TYPE_BINFO (fromtype),
- flags, &candidates);
+ flags, &candidates, complain);
for (cand = candidates; cand != old_candidates; cand = cand->next)
{
@@ -3517,7 +3538,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
= implicit_conversion (totype,
rettype,
0,
- /*c_cast_p=*/false, convflags);
+ /*c_cast_p=*/false, convflags,
+ complain);
/* If LOOKUP_NO_TEMP_BIND isn't set, then this is
copy-initialization. In that case, "The result of the
@@ -3582,13 +3604,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
return NULL;
}
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (cand == 0)
{
- if (flags & LOOKUP_COMPLAIN)
+ if ((flags & LOOKUP_COMPLAIN)
+ && (complain & tf_error))
{
error ("conversion from %qT to %qT is ambiguous",
- fromtype, totype);
+ fromtype, totype);
print_z_candidates (location_of (expr), candidates);
}
@@ -3628,13 +3651,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
/* Wrapper for above. */
tree
-build_user_type_conversion (tree totype, tree expr, int flags)
+build_user_type_conversion (tree totype, tree expr, int flags,
+ tsubst_flags_t complain)
{
struct z_candidate *cand;
tree ret;
bool subtime = timevar_cond_start (TV_OVERLOAD);
- cand = build_user_type_conversion_1 (totype, expr, flags);
+ cand = build_user_type_conversion_1 (totype, expr, flags, complain);
if (cand)
{
@@ -3642,7 +3666,7 @@ build_user_type_conversion (tree totype, tree expr, int flags)
ret = error_mark_node;
else
{
- expr = convert_like (cand->second_conv, expr, tf_warning_or_error);
+ expr = convert_like (cand->second_conv, expr, complain);
ret = convert_from_reference (expr);
}
}
@@ -3679,7 +3703,7 @@ build_integral_nontype_arg_conv (tree type, tree expr, tsubst_flags_t complain)
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
/*c_cast_p=*/false,
- LOOKUP_IMPLICIT);
+ LOOKUP_IMPLICIT, complain);
/* for a non-type template-parameter of integral or
enumeration type, integral promotions (4.5) and integral
@@ -3763,7 +3787,7 @@ static struct z_candidate *
perform_overload_resolution (tree fn,
const VEC(tree,gc) *args,
struct z_candidate **candidates,
- bool *any_viable_p)
+ bool *any_viable_p, tsubst_flags_t complain)
{
struct z_candidate *cand;
tree explicit_targs;
@@ -3796,11 +3820,11 @@ perform_overload_resolution (tree fn,
/*conversion_path=*/NULL_TREE,
/*access_path=*/NULL_TREE,
LOOKUP_NORMAL,
- candidates);
+ candidates, complain);
*candidates = splice_viable (*candidates, pedantic, any_viable_p);
if (*any_viable_p)
- cand = tourney (*candidates);
+ cand = tourney (*candidates, complain);
else
cand = NULL;
@@ -3872,7 +3896,8 @@ build_new_function_call (tree fn, VEC(tree,gc) **args, bool koenig_p,
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
- cand = perform_overload_resolution (fn, *args, &candidates, &any_viable_p);
+ cand = perform_overload_resolution (fn, *args, &candidates, &any_viable_p,
+ complain);
if (!cand)
{
@@ -3918,7 +3943,7 @@ build_new_function_call (tree fn, VEC(tree,gc) **args, bool koenig_p,
tree
build_operator_new_call (tree fnname, VEC(tree,gc) **args,
tree *size, tree *cookie_size,
- tree *fn)
+ tree *fn, tsubst_flags_t complain)
{
tree fns;
struct z_candidate *candidates;
@@ -3928,7 +3953,7 @@ build_operator_new_call (tree fnname, VEC(tree,gc) **args,
if (fn)
*fn = NULL_TREE;
VEC_safe_insert (tree, gc, *args, 0, *size);
- *args = resolve_args (*args, tf_warning_or_error);
+ *args = resolve_args (*args, complain);
if (*args == NULL)
return error_mark_node;
@@ -3944,13 +3969,15 @@ build_operator_new_call (tree fnname, VEC(tree,gc) **args,
fns = lookup_function_nonclass (fnname, *args, /*block_p=*/false);
/* Figure out what function is being called. */
- cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p);
+ cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p,
+ complain);
/* If no suitable function could be found, issue an error message
and give up. */
if (!cand)
{
- print_error_for_call_failure (fns, *args, any_viable_p, candidates);
+ if (complain & tf_error)
+ print_error_for_call_failure (fns, *args, any_viable_p, candidates);
return error_mark_node;
}
@@ -4001,7 +4028,7 @@ build_operator_new_call (tree fnname, VEC(tree,gc) **args,
*fn = cand->fn;
/* Build the CALL_EXPR. */
- return build_over_call (cand, LOOKUP_NORMAL, tf_warning_or_error);
+ return build_over_call (cand, LOOKUP_NORMAL, complain);
}
/* Build a new call to operator(). This may change ARGS. */
@@ -4057,7 +4084,7 @@ build_op_call_1 (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
first_mem_arg, *args, NULL_TREE,
NULL_TREE, false,
BASELINK_BINFO (fns), BASELINK_ACCESS_BINFO (fns),
- LOOKUP_NORMAL, &candidates);
+ LOOKUP_NORMAL, &candidates, complain);
}
convs = lookup_conversions (type);
@@ -4085,11 +4112,11 @@ build_op_call_1 (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
add_template_conv_candidate
(&candidates, fn, obj, NULL_TREE, *args, totype,
/*access_path=*/NULL_TREE,
- /*conversion_path=*/NULL_TREE);
+ /*conversion_path=*/NULL_TREE, complain);
else
add_conv_candidate (&candidates, fn, obj, NULL_TREE,
*args, /*conversion_path=*/NULL_TREE,
- /*access_path=*/NULL_TREE);
+ /*access_path=*/NULL_TREE, complain);
}
}
@@ -4106,7 +4133,7 @@ build_op_call_1 (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
}
else
{
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (cand == 0)
{
if (complain & tf_error)
@@ -4251,7 +4278,7 @@ op_error (enum tree_code code, enum tree_code code2,
convert E1 to E2 in [expr.cond]. */
static conversion *
-conditional_conversion (tree e1, tree e2)
+conditional_conversion (tree e1, tree e2, tsubst_flags_t complain)
{
tree t1 = non_reference (TREE_TYPE (e1));
tree t2 = non_reference (TREE_TYPE (e2));
@@ -4271,7 +4298,8 @@ conditional_conversion (tree e1, tree e2)
e1,
/*c_cast_p=*/false,
LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND
- |LOOKUP_ONLYCONVERTING);
+ |LOOKUP_ONLYCONVERTING,
+ complain);
if (conv)
return conv;
}
@@ -4309,7 +4337,7 @@ conditional_conversion (tree e1, tree e2)
converted to the type that expression E2 would have if E2 were
converted to an rvalue (or the type it has, if E2 is an rvalue). */
return implicit_conversion (t2, t1, e1, /*c_cast_p=*/false,
- LOOKUP_IMPLICIT);
+ LOOKUP_IMPLICIT, complain);
}
/* Implement [expr.cond]. ARG1, ARG2, and ARG3 are the three
@@ -4455,8 +4483,8 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
- conv2 = conditional_conversion (arg2, arg3);
- conv3 = conditional_conversion (arg3, arg2);
+ conv2 = conditional_conversion (arg2, arg3, complain);
+ conv3 = conditional_conversion (arg3, arg2, complain);
/* [expr.cond]
@@ -4568,7 +4596,7 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
NOP_EXPR,
ansi_opname (COND_EXPR),
args,
- LOOKUP_NORMAL);
+ LOOKUP_NORMAL, complain);
/* [expr.cond]
@@ -4584,7 +4612,7 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
}
return error_mark_node;
}
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (!cand)
{
if (complain & tf_error)
@@ -4793,7 +4821,8 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args,
tree explicit_targs, bool template_only,
tree conversion_path, tree access_path,
int flags,
- struct z_candidate **candidates)
+ struct z_candidate **candidates,
+ tsubst_flags_t complain)
{
tree ctype;
const VEC(tree,gc) *non_static_args;
@@ -4899,7 +4928,8 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args,
access_path,
conversion_path,
flags,
- strict);
+ strict,
+ complain);
else if (!template_only)
add_function_candidate (candidates,
fn,
@@ -4908,7 +4938,8 @@ add_candidates (tree fns, tree first_arg, const VEC(tree,gc) *args,
fn_args,
access_path,
conversion_path,
- flags);
+ flags,
+ complain);
}
}
@@ -4999,7 +5030,7 @@ build_new_op_1 (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
add_candidates (lookup_function_nonclass (fnname, arglist, /*block_p=*/true),
NULL_TREE, arglist, NULL_TREE,
NULL_TREE, false, NULL_TREE, NULL_TREE,
- flags, &candidates);
+ flags, &candidates, complain);
/* Add class-member operators to the candidate set. */
if (CLASS_TYPE_P (TREE_TYPE (arg1)))
{
@@ -5017,14 +5048,15 @@ build_new_op_1 (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
NULL_TREE, false,
BASELINK_BINFO (fns),
BASELINK_ACCESS_BINFO (fns),
- flags, &candidates);
+ flags, &candidates, complain);
}
args[0] = arg1;
args[1] = arg2;
args[2] = NULL_TREE;
- add_builtin_candidates (&candidates, code, code2, fnname, args, flags);
+ add_builtin_candidates (&candidates, code, code2, fnname, args,
+ flags, complain);
switch (code)
{
@@ -5113,7 +5145,7 @@ build_new_op_1 (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
}
else
{
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (cand == 0)
{
if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
@@ -5140,7 +5172,7 @@ build_new_op_1 (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
{
struct candidate_warning *w;
for (w = cand->warnings; w; w = w->next)
- joust (cand, w->loser, 1);
+ joust (cand, w->loser, 1, complain);
}
/* Check for comparison of different enum types. */
@@ -5770,7 +5802,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
if (complain & tf_error)
{
/* Call build_user_type_conversion again for the error. */
- build_user_type_conversion (totype, convs->u.expr, LOOKUP_NORMAL);
+ build_user_type_conversion (totype, convs->u.expr, LOOKUP_NORMAL,
+ complain);
if (fn)
error (" initializing argument %P of %q+D", argnum, fn);
}
@@ -6010,7 +6043,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
required. Return the converted value. */
tree
-convert_arg_to_ellipsis (tree arg)
+convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
{
tree arg_type;
@@ -6018,7 +6051,7 @@ convert_arg_to_ellipsis (tree arg)
The lvalue-to-rvalue, array-to-pointer, and function-to-pointer
standard conversions are performed. */
- arg = decay_conversion (arg, tf_warning_or_error);
+ arg = decay_conversion (arg, complain);
arg_type = TREE_TYPE (arg);
/* [expr.call]
@@ -6032,7 +6065,8 @@ convert_arg_to_ellipsis (tree arg)
< TYPE_PRECISION (double_type_node))
&& !DECIMAL_FLOAT_MODE_P (TYPE_MODE (arg_type)))
{
- if (warn_double_promotion && !c_inhibit_evaluation_warnings)
+ if ((complain & tf_warning)
+ && warn_double_promotion && !c_inhibit_evaluation_warnings)
warning (OPT_Wdouble_promotion,
"implicit conversion from %qT to %qT when passing "
"argument to function",
@@ -6045,8 +6079,9 @@ convert_arg_to_ellipsis (tree arg)
{
if (SCOPED_ENUM_P (arg_type) && !abi_version_at_least (6))
{
- warning (OPT_Wabi, "scoped enum %qT will not promote to an "
- "integral type in a future version of GCC", arg_type);
+ if (complain & tf_warning)
+ warning (OPT_Wabi, "scoped enum %qT will not promote to an "
+ "integral type in a future version of GCC", arg_type);
arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg);
}
arg = perform_integral_promotions (arg);
@@ -6064,7 +6099,7 @@ convert_arg_to_ellipsis (tree arg)
/* Build up a real lvalue-to-rvalue conversion in case the
copy constructor is trivial but not callable. */
if (!cp_unevaluated_operand && CLASS_TYPE_P (arg_type))
- force_rvalue (arg, tf_warning_or_error);
+ force_rvalue (arg, complain);
/* [expr.call] 5.2.2/7:
Passing a potentially-evaluated argument of class type (Clause 9)
@@ -6080,8 +6115,13 @@ convert_arg_to_ellipsis (tree arg)
if (cp_unevaluated_operand == 0
&& (type_has_nontrivial_copy_init (arg_type)
|| TYPE_HAS_NONTRIVIAL_DESTRUCTOR (arg_type)))
- error ("cannot pass objects of non-trivially-copyable "
- "type %q#T through %<...%>", arg_type);
+ {
+ if (complain & tf_error)
+ error ("cannot pass objects of non-trivially-copyable "
+ "type %q#T through %<...%>", arg_type);
+ else
+ return error_mark_node;
+ }
}
return arg;
@@ -6153,7 +6193,8 @@ pop_defarg_context (void)
{ VEC_pop (tree, default_arg_context); }
tree
-convert_default_arg (tree type, tree arg, tree fn, int parmnum)
+convert_default_arg (tree type, tree arg, tree fn, int parmnum,
+ tsubst_flags_t complain)
{
int i;
tree t;
@@ -6165,7 +6206,8 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
FOR_EACH_VEC_ELT (tree, default_arg_context, i, t)
if (t == fn)
{
- error ("recursive evaluation of default argument for %q#D", fn);
+ if (complain & tf_error)
+ error ("recursive evaluation of default argument for %q#D", fn);
return error_mark_node;
}
@@ -6173,8 +6215,9 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
conversion cannot be performed. */
if (TREE_CODE (arg) == DEFAULT_ARG)
{
- error ("call to %qD uses the default argument for parameter %P, which "
- "is not yet defined", fn, parmnum);
+ if (complain & tf_error)
+ error ("call to %qD uses the default argument for parameter %P, which "
+ "is not yet defined", fn, parmnum);
return error_mark_node;
}
@@ -6198,17 +6241,17 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
arg = break_out_target_exprs (arg);
if (TREE_CODE (arg) == CONSTRUCTOR)
{
- arg = digest_init (type, arg, tf_warning_or_error);
+ arg = digest_init (type, arg, complain);
arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
ICR_DEFAULT_ARGUMENT, fn, parmnum,
- tf_warning_or_error);
+ complain);
}
else
{
arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
ICR_DEFAULT_ARGUMENT, fn, parmnum,
- tf_warning_or_error);
- arg = convert_for_arg_passing (type, arg);
+ complain);
+ arg = convert_for_arg_passing (type, arg, complain);
}
pop_deferring_access_checks();
@@ -6243,7 +6286,7 @@ type_passed_as (tree type)
/* Actually perform the appropriate conversion. */
tree
-convert_for_arg_passing (tree type, tree val)
+convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
{
tree bitfield_type;
@@ -6277,7 +6320,8 @@ convert_for_arg_passing (tree type, tree val)
&& INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
TYPE_SIZE (integer_type_node)))
val = perform_integral_promotions (val);
- if (warn_missing_format_attribute)
+ if ((complain & tf_warning)
+ && warn_missing_format_attribute)
{
tree rhstype = TREE_TYPE (val);
const enum tree_code coder = TREE_CODE (rhstype);
@@ -6383,7 +6427,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
{
struct candidate_warning *w;
for (w = cand->warnings; w; w = w->next)
- joust (cand, w->loser, 1);
+ joust (cand, w->loser, 1, complain);
}
/* Make =delete work with SFINAE. */
@@ -6611,7 +6655,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
? complain
: complain & (~tf_warning));
- val = convert_for_arg_passing (type, val);
+ val = convert_for_arg_passing (type, val, complain);
if (val == error_mark_node)
return error_mark_node;
else
@@ -6625,7 +6669,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return error_mark_node;
argarray[j++] = convert_default_arg (TREE_VALUE (parm),
TREE_PURPOSE (parm),
- fn, i - is_method);
+ fn, i - is_method,
+ complain);
}
/* Ellipsis */
@@ -6636,7 +6681,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
/* Do no conversions for magic varargs. */
a = mark_type_use (a);
else
- a = convert_arg_to_ellipsis (a);
+ a = convert_arg_to_ellipsis (a, complain);
argarray[j++] = a;
}
@@ -7275,13 +7320,14 @@ build_new_method_call_1 (tree instance, tree fns, VEC(tree,gc) **args,
/* Otherwise go ahead with overload resolution. */
add_list_candidates (fns, first_mem_arg, init_list,
basetype, explicit_targs, template_only,
- conversion_path, access_binfo, flags, &candidates);
+ conversion_path, access_binfo, flags,
+ &candidates, complain);
}
else
{
add_candidates (fns, first_mem_arg, user_args, optype,
explicit_targs, template_only, conversion_path,
- access_binfo, flags, &candidates);
+ access_binfo, flags, &candidates, complain);
}
any_viable_p = false;
candidates = splice_viable (candidates, pedantic, &any_viable_p);
@@ -7318,7 +7364,7 @@ build_new_method_call_1 (tree instance, tree fns, VEC(tree,gc) **args,
}
else
{
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (cand == 0)
{
char *pretty_name;
@@ -8013,7 +8059,8 @@ add_warning (struct z_candidate *winner, struct z_candidate *loser)
0: cand1 and cand2 are indistinguishable */
static int
-joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
+joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
+ tsubst_flags_t complain)
{
int winner = 0;
int off1 = 0, off2 = 0;
@@ -8076,7 +8123,8 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
if (comp != 0)
{
- if (warn_sign_promo
+ if ((complain & tf_warning)
+ && warn_sign_promo
&& (CONVERSION_RANK (t1) + CONVERSION_RANK (t2)
== cr_std + cr_promotion)
&& t1->kind == ck_std
@@ -8121,7 +8169,8 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
/* warn about confusing overload resolution for user-defined conversions,
either between a constructor and a conversion op, or between two
conversion ops. */
- if (winner && warn_conversion && cand1->second_conv
+ if ((complain & tf_warning)
+ && winner && warn_conversion && cand1->second_conv
&& (!DECL_CONSTRUCTOR_P (cand1->fn) || !DECL_CONSTRUCTOR_P (cand2->fn))
&& winner != compare_ics (cand1->second_conv, cand2->second_conv))
{
@@ -8283,12 +8332,18 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
{
if (warn)
{
- permerror (input_location, "default argument mismatch in "
- "overload resolution");
- inform (input_location,
- " candidate 1: %q+#F", cand1->fn);
- inform (input_location,
- " candidate 2: %q+#F", cand2->fn);
+ if (complain & tf_error)
+ {
+ permerror (input_location,
+ "default argument mismatch in "
+ "overload resolution");
+ inform (input_location,
+ " candidate 1: %q+#F", cand1->fn);
+ inform (input_location,
+ " candidate 2: %q+#F", cand2->fn);
+ }
+ else
+ return 0;
}
else
add_warning (cand1, cand2);
@@ -8305,7 +8360,7 @@ tweak:
/* Extension: If the worst conversion for one candidate is worse than the
worst conversion for the other, take the first. */
- if (!pedantic)
+ if (!pedantic && (complain & tf_warning_or_error))
{
conversion_rank rank1 = cr_identity, rank2 = cr_identity;
struct z_candidate *w = 0, *l = 0;
@@ -8351,7 +8406,7 @@ tweak:
algorithm. */
static struct z_candidate *
-tourney (struct z_candidate *candidates)
+tourney (struct z_candidate *candidates, tsubst_flags_t complain)
{
struct z_candidate *champ = candidates, *challenger;
int fate;
@@ -8362,7 +8417,7 @@ tourney (struct z_candidate *candidates)
for (challenger = champ->next; challenger; )
{
- fate = joust (champ, challenger, 0);
+ fate = joust (champ, challenger, 0, complain);
if (fate == 1)
challenger = challenger->next;
else
@@ -8392,7 +8447,7 @@ tourney (struct z_candidate *candidates)
&& !(champ_compared_to_predecessor && challenger->next == champ);
challenger = challenger->next)
{
- fate = joust (champ, challenger, 0);
+ fate = joust (champ, challenger, 0, complain);
if (fate != 1)
return NULL;
}
@@ -8403,15 +8458,16 @@ tourney (struct z_candidate *candidates)
/* Returns nonzero if things of type FROM can be converted to TO. */
bool
-can_convert (tree to, tree from)
+can_convert (tree to, tree from, tsubst_flags_t complain)
{
- return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT);
+ return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT, complain);
}
/* Returns nonzero if ARG (of type FROM) can be converted to TO. */
bool
-can_convert_arg (tree to, tree from, tree arg, int flags)
+can_convert_arg (tree to, tree from, tree arg, int flags,
+ tsubst_flags_t complain)
{
conversion *t;
void *p;
@@ -8421,7 +8477,7 @@ can_convert_arg (tree to, tree from, tree arg, int flags)
p = conversion_obstack_alloc (0);
t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
- flags);
+ flags, complain);
ok_p = (t && !t->bad_p);
/* Free all the conversions we allocated. */
@@ -8433,7 +8489,8 @@ can_convert_arg (tree to, tree from, tree arg, int flags)
/* Like can_convert_arg, but allows dubious conversions as well. */
bool
-can_convert_arg_bad (tree to, tree from, tree arg, int flags)
+can_convert_arg_bad (tree to, tree from, tree arg, int flags,
+ tsubst_flags_t complain)
{
conversion *t;
void *p;
@@ -8442,7 +8499,7 @@ can_convert_arg_bad (tree to, tree from, tree arg, int flags)
p = conversion_obstack_alloc (0);
/* Try to perform the conversion. */
t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
- flags);
+ flags, complain);
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
@@ -8456,7 +8513,8 @@ can_convert_arg_bad (tree to, tree from, tree arg, int flags)
doing a bad conversion, convert_like will complain. */
tree
-perform_implicit_conversion_flags (tree type, tree expr, tsubst_flags_t complain, int flags)
+perform_implicit_conversion_flags (tree type, tree expr,
+ tsubst_flags_t complain, int flags)
{
conversion *conv;
void *p;
@@ -8469,7 +8527,7 @@ perform_implicit_conversion_flags (tree type, tree expr, tsubst_flags_t complain
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
/*c_cast_p=*/false,
- flags);
+ flags, complain);
if (!conv)
{
@@ -8510,7 +8568,8 @@ perform_implicit_conversion_flags (tree type, tree expr, tsubst_flags_t complain
tree
perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain)
{
- return perform_implicit_conversion_flags (type, expr, complain, LOOKUP_IMPLICIT);
+ return perform_implicit_conversion_flags (type, expr, complain,
+ LOOKUP_IMPLICIT);
}
/* Convert EXPR to TYPE (as a direct-initialization) if that is
@@ -8554,7 +8613,7 @@ perform_direct_initialization_if_possible (tree type,
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
c_cast_p,
- LOOKUP_NORMAL);
+ LOOKUP_NORMAL, complain);
if (!conv || conv->bad_p)
expr = NULL_TREE;
else
@@ -8768,7 +8827,7 @@ initialize_reference (tree type, tree expr,
p = conversion_obstack_alloc (0);
conv = reference_binding (type, TREE_TYPE (expr), expr, /*c_cast_p=*/false,
- flags);
+ flags, complain);
if (!conv || conv->bad_p)
{
if (complain & tf_error)
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 416c640c68c..c3d1f23184b 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -1273,7 +1273,8 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
for (parm = defparm; parm && parm != void_list_node;
parm = TREE_CHAIN (parm), i++)
argarray[i] = convert_default_arg (TREE_VALUE (parm),
- TREE_PURPOSE (parm), fn, i);
+ TREE_PURPOSE (parm), fn, i,
+ tf_warning_or_error);
t = build_call_a (fn, i, argarray);
t = fold_convert (void_type_node, t);
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
@@ -1306,7 +1307,7 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
parm = TREE_CHAIN (parm), i++)
argarray[i] = convert_default_arg (TREE_VALUE (parm),
TREE_PURPOSE (parm),
- fn, i);
+ fn, i, tf_warning_or_error);
t = build_call_a (fn, i, argarray);
t = fold_convert (void_type_node, t);
return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 429ac2c5c74..e046069182c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4862,11 +4862,13 @@ extern bool null_ptr_cst_p (tree);
extern bool null_member_pointer_value_p (tree);
extern bool sufficient_parms_p (const_tree);
extern tree type_decays_to (tree);
-extern tree build_user_type_conversion (tree, tree, int);
+extern tree build_user_type_conversion (tree, tree, int,
+ tsubst_flags_t);
extern tree build_new_function_call (tree, VEC(tree,gc) **, bool,
tsubst_flags_t);
extern tree build_operator_new_call (tree, VEC(tree,gc) **, tree *,
- tree *, tree *);
+ tree *, tree *,
+ tsubst_flags_t);
extern tree build_new_method_call (tree, tree, VEC(tree,gc) **,
tree, int, tree *,
tsubst_flags_t);
@@ -4878,18 +4880,21 @@ extern tree build_new_op (enum tree_code, int, tree,
extern tree build_op_call (tree, VEC(tree,gc) **,
tsubst_flags_t);
extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree, tree);
-extern bool can_convert (tree, tree);
-extern bool can_convert_arg (tree, tree, tree, int);
-extern bool can_convert_arg_bad (tree, tree, tree, int);
+extern bool can_convert (tree, tree, tsubst_flags_t);
+extern bool can_convert_arg (tree, tree, tree, int,
+ tsubst_flags_t);
+extern bool can_convert_arg_bad (tree, tree, tree, int,
+ tsubst_flags_t);
extern bool enforce_access (tree, tree, tree);
extern void push_defarg_context (tree);
extern void pop_defarg_context (void);
-extern tree convert_default_arg (tree, tree, tree, int);
-extern tree convert_arg_to_ellipsis (tree);
+extern tree convert_default_arg (tree, tree, tree, int,
+ tsubst_flags_t);
+extern tree convert_arg_to_ellipsis (tree, tsubst_flags_t);
extern tree build_x_va_arg (tree, tree);
extern tree cxx_type_promotes_to (tree);
extern tree type_passed_as (tree);
-extern tree convert_for_arg_passing (tree, tree);
+extern tree convert_for_arg_passing (tree, tree, tsubst_flags_t);
extern bool is_properly_derived_from (tree, tree);
extern tree initialize_reference (tree, tree, int,
tsubst_flags_t);
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 09a589efd02..3dab372a301 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -408,12 +408,12 @@ convert_to_reference (tree reftype, tree expr, int convtype,
tree rval = NULL_TREE;
tree rval_as_conversion = NULL_TREE;
bool can_convert_intype_to_type;
+ tsubst_flags_t complain = ((flags & LOOKUP_COMPLAIN)
+ ? tf_warning_or_error : tf_none);
if (TREE_CODE (type) == FUNCTION_TYPE
&& TREE_TYPE (expr) == unknown_type_node)
- expr = instantiate_type (type, expr,
- (flags & LOOKUP_COMPLAIN)
- ? tf_warning_or_error : tf_none);
+ expr = instantiate_type (type, expr, complain);
if (expr == error_mark_node)
return error_mark_node;
@@ -425,7 +425,8 @@ convert_to_reference (tree reftype, tree expr, int convtype,
intype = TYPE_MAIN_VARIANT (intype);
- can_convert_intype_to_type = can_convert (type, intype);
+ can_convert_intype_to_type = can_convert (type, intype, complain);
+
if (!can_convert_intype_to_type
&& (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype)
&& ! (flags & LOOKUP_NO_CONVERSION))
@@ -445,7 +446,7 @@ convert_to_reference (tree reftype, tree expr, int convtype,
}
}
- if (((convtype & CONV_STATIC) && can_convert (intype, type))
+ if (((convtype & CONV_STATIC) && can_convert (intype, type, complain))
|| ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type))
{
if (flags & LOOKUP_COMPLAIN)
@@ -821,7 +822,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
/* For copy-initialization, first we create a temp of the proper type
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);
+ ctor = build_user_type_conversion (type, ctor, flags,
+ tf_warning_or_error);
else
{
VEC(tree,gc) *ctor_vec = make_tree_vector_single (ctor);
@@ -1451,7 +1453,8 @@ build_type_conversion (tree xtype, tree expr)
{
/* C++: check to see if we can convert this aggregate type
into the required type. */
- return build_user_type_conversion (xtype, expr, LOOKUP_NORMAL);
+ return build_user_type_conversion (xtype, expr, LOOKUP_NORMAL,
+ tf_warning_or_error);
}
/* Convert the given EXPR to one of a group of types suitable for use in an
@@ -1609,7 +1612,8 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
if (winner)
{
tree type = non_reference (TREE_TYPE (TREE_TYPE (winner)));
- return build_user_type_conversion (type, expr, LOOKUP_NORMAL);
+ return build_user_type_conversion (type, expr, LOOKUP_NORMAL,
+ tf_warning_or_error);
}
return NULL_TREE;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 870b6b3092c..28c7cee4d90 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5266,7 +5266,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
valid aggregate initialization. */
&& !first_initializer_p
&& (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init))
- || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL)))
+ || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL,
+ complain)))
{
d->cur++;
return init;
@@ -10602,7 +10603,8 @@ check_default_argument (tree decl, tree arg)
A default argument expression is implicitly converted to the
parameter type. */
if (!TREE_TYPE (arg)
- || !can_convert_arg (decl_type, TREE_TYPE (arg), arg, LOOKUP_NORMAL))
+ || !can_convert_arg (decl_type, TREE_TYPE (arg), arg, LOOKUP_NORMAL,
+ tf_warning_or_error))
{
if (decl)
error ("default argument for %q#D has type %qT",
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index d4c357facd7..e8debb870d6 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -2381,7 +2381,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
alloc_call = build_operator_new_call (fnname, placement,
&size, &cookie_size,
- &alloc_fn);
+ &alloc_fn, complain);
}
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 636909db5c0..409e6b9cd52 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6063,7 +6063,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
"because it is of type %qT", expr, type,
TREE_TYPE (expr));
/* If we are just one standard conversion off, explain. */
- if (can_convert (type, TREE_TYPE (expr)))
+ if (can_convert (type, TREE_TYPE (expr), complain))
inform (input_location,
"standard conversions are not allowed in this context");
return NULL_TREE;
@@ -15128,14 +15128,15 @@ check_non_deducible_conversion (tree parm, tree arg, int strict,
if (strict == DEDUCE_CONV)
{
- if (can_convert_arg (type, parm, NULL_TREE, flags))
+ if (can_convert_arg (type, parm, NULL_TREE, flags,
+ explain_p ? tf_warning_or_error : tf_none))
return unify_success (explain_p);
}
else if (strict != DEDUCE_EXACT)
{
if (can_convert_arg (parm, type,
TYPE_P (arg) ? NULL_TREE : arg,
- flags))
+ flags, explain_p ? tf_warning_or_error : tf_none))
return unify_success (explain_p);
}
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 14d272e10e8..19ef5967a80 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1,7 +1,8 @@
/* Breadth-first and depth-first routines for
searching multiple-inheritance lattice for GNU C++.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
+ 1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011,
+ 2012
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
@@ -1891,7 +1892,8 @@ check_final_overrider (tree overrider, tree basefn)
}
}
else if (!pedantic
- && can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type)))
+ && can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type),
+ tf_warning_or_error))
/* GNU extension, allow trivial pointer conversions such as
converting to void *, or qualification conversion. */
{
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 3aabbe95c56..fb2f1bc6bbb 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -55,8 +55,8 @@ static bool comp_except_types (tree, tree, bool);
static bool comp_array_types (const_tree, const_tree, bool);
static tree pointer_diff (tree, tree, tree);
static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
-static void casts_away_constness_r (tree *, tree *);
-static bool casts_away_constness (tree, tree);
+static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
+static bool casts_away_constness (tree, tree, tsubst_flags_t);
static void maybe_warn_about_returning_address_of_local (tree);
static tree lookup_destructor (tree, tree, tree);
static void warn_args_num (location_t, tree, bool);
@@ -3500,7 +3500,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
parmval = convert_for_initialization
(NULL_TREE, type, val, flags,
ICR_ARGPASS, fndecl, i, complain);
- parmval = convert_for_arg_passing (type, parmval);
+ parmval = convert_for_arg_passing (type, parmval, complain);
}
if (parmval == error_mark_node)
@@ -3517,7 +3517,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
types. */
val = require_complete_type_sfinae (val, complain);
else
- val = convert_arg_to_ellipsis (val);
+ val = convert_arg_to_ellipsis (val, complain);
VEC_replace (tree, *values, i, val);
}
@@ -3543,7 +3543,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
tree parmval
= convert_default_arg (TREE_VALUE (typetail),
TREE_PURPOSE (typetail),
- fndecl, i);
+ fndecl, i, complain);
if (parmval == error_mark_node)
return -1;
@@ -5782,7 +5782,7 @@ check_for_casting_away_constness (tree src_type, tree dest_type,
if (cast == CAST_EXPR && !warn_cast_qual)
return false;
- if (!casts_away_constness (src_type, dest_type))
+ if (!casts_away_constness (src_type, dest_type, complain))
return false;
switch (cast)
@@ -5932,7 +5932,8 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
&& DERIVED_FROM_P (intype, TREE_TYPE (type))
&& can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
build_pointer_type (TYPE_MAIN_VARIANT
- (TREE_TYPE (type))))
+ (TREE_TYPE (type))),
+ complain)
&& (c_cast_p
|| at_least_as_qualified_p (TREE_TYPE (type), intype)))
{
@@ -6059,7 +6060,8 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
&& can_convert (build_pointer_type (TYPE_MAIN_VARIANT
(TREE_TYPE (intype))),
build_pointer_type (TYPE_MAIN_VARIANT
- (TREE_TYPE (type)))))
+ (TREE_TYPE (type))),
+ complain))
{
tree base;
@@ -6100,7 +6102,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
t1 = intype;
t2 = type;
}
- if (can_convert (t1, t2) || can_convert (t2, t1))
+ if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain))
{
if (!c_cast_p
&& check_for_casting_away_constness (intype, type,
@@ -7301,7 +7303,8 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p,
tree n;
if (!force
- && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn, LOOKUP_NORMAL))
+ && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn,
+ LOOKUP_NORMAL, complain))
error ("invalid conversion to type %qT from type %qT",
to_type, pfn_type);
@@ -7566,7 +7569,7 @@ convert_for_assignment (tree type, tree rhs,
We allow bad conversions here because by the time we get to this point
we are committed to doing the conversion. If we end up doing a bad
conversion, convert_like will complain. */
- if (!can_convert_arg_bad (type, rhstype, rhs, flags))
+ if (!can_convert_arg_bad (type, rhstype, rhs, flags, complain))
{
/* When -Wno-pmf-conversions is use, we just silently allow
conversions from pointers-to-members to plain pointers. If
@@ -8419,7 +8422,7 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl)
if and only if there is no implicit conversion from T1 to T2. */
static void
-casts_away_constness_r (tree *t1, tree *t2)
+casts_away_constness_r (tree *t1, tree *t2, tsubst_flags_t complain)
{
int quals1;
int quals2;
@@ -8469,7 +8472,7 @@ casts_away_constness_r (tree *t1, tree *t2)
else
*t2 = TREE_TYPE (*t2);
- casts_away_constness_r (t1, t2);
+ casts_away_constness_r (t1, t2, complain);
*t1 = build_pointer_type (*t1);
*t2 = build_pointer_type (*t2);
*t1 = cp_build_qualified_type (*t1, quals1);
@@ -8485,7 +8488,7 @@ casts_away_constness_r (tree *t1, tree *t2)
*/
static bool
-casts_away_constness (tree t1, tree t2)
+casts_away_constness (tree t1, tree t2, tsubst_flags_t complain)
{
if (TREE_CODE (t2) == REFERENCE_TYPE)
{
@@ -8497,7 +8500,8 @@ casts_away_constness (tree t1, tree t2)
casts away constness. */
t1 = (TREE_CODE (t1) == REFERENCE_TYPE ? TREE_TYPE (t1) : t1);
return casts_away_constness (build_pointer_type (t1),
- build_pointer_type (TREE_TYPE (t2)));
+ build_pointer_type (TREE_TYPE (t2)),
+ complain);
}
if (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2))
@@ -8510,7 +8514,8 @@ casts_away_constness (tree t1, tree t2)
constness. */
return casts_away_constness
(build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t1)),
- build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)));
+ build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)),
+ complain);
/* Casting away constness is only something that makes sense for
pointer or reference types. */
@@ -8521,8 +8526,8 @@ casts_away_constness (tree t1, tree t2)
/* Top-level qualifiers don't matter. */
t1 = TYPE_MAIN_VARIANT (t1);
t2 = TYPE_MAIN_VARIANT (t2);
- casts_away_constness_r (&t1, &t2);
- if (!can_convert (t2, t1))
+ casts_away_constness_r (&t1, &t2, complain);
+ if (!can_convert (t2, t1, complain))
return true;
return false;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0a4d974ef08..5f14b79cdd7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,8 +1,14 @@
+2012-04-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52363
+ * g++.dg/cpp0x/sfinae35.C: New.
+ * g++.dg/cpp0x/sfinae36.C: Likewise.
+
2012-04-24 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR target/47197
* gcc.target/powerpc/pr47197.c: New test.
-
+
2012-04-24 Richard Guenther <rguenther@suse.de>
PR tree-optimization/53085
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae35.C b/gcc/testsuite/g++.dg/cpp0x/sfinae35.C
new file mode 100644
index 00000000000..21df10cf435
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/sfinae35.C
@@ -0,0 +1,13 @@
+// PR c++/52363
+// { dg-options -std=c++11 }
+
+#include <type_traits>
+
+struct proxy
+{
+ void operator=(int const&);
+ void operator=(int&&) const;
+};
+
+static_assert( !std::is_assignable<proxy, int>::value, "" );
+static_assert( std::is_assignable<const proxy, int>::value, "" );
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae36.C b/gcc/testsuite/g++.dg/cpp0x/sfinae36.C
new file mode 100644
index 00000000000..79509a1d1e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/sfinae36.C
@@ -0,0 +1,13 @@
+// PR c++/52363
+// { dg-options "-std=c++11 -pedantic" }
+
+#include <type_traits>
+
+struct proxy
+{
+ void operator=(int const&);
+ void operator=(int&&) const;
+};
+
+static_assert( !std::is_assignable<proxy, int>::value, "" );
+static_assert( std::is_assignable<const proxy, int>::value, "" );