Hi,
thus I'm handling this issue per the discussion in the audit trail: by
adding a tsubst_flags_t parameter to 'joust' and 'tourney' and adjusting
the callers. Then 'joust' deals with SFINAE as-if pedantic mode were
unconditionally active.
Tested x86_64-linux.
Thanks,
Paolo.
////////////////////////
/cp
2012-04-18 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/52363
* call.c (tourney): Add tsubst_flags_t parameter.
(joust): Likewise, use it to handle SFINAE as if pedantic.
(build_user_type_conversion_1, perform_overload_resolution,
build_op_call_1, build_conditional_expr_1, build_new_op_1,
build_over_call, build_new_method_call_1): Adjust.
/testsuite
2012-04-18 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/52363
* testsuite/g++.dg/cpp0x/sfinae35.C: New.
* testsuite/g++.dg/cpp0x/sfinae36.C: Likewise.
Index: testsuite/g++.dg/cpp0x/sfinae35.C
===================================================================
--- testsuite/g++.dg/cpp0x/sfinae35.C (revision 0)
+++ testsuite/g++.dg/cpp0x/sfinae35.C (revision 0)
@@ -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, "" );
Index: testsuite/g++.dg/cpp0x/sfinae36.C
===================================================================
--- testsuite/g++.dg/cpp0x/sfinae36.C (revision 0)
+++ testsuite/g++.dg/cpp0x/sfinae36.C (revision 0)
@@ -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, "" );
Index: cp/call.c
===================================================================
--- cp/call.c (revision 186573)
+++ cp/call.c (working copy)
@@ -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);
@@ -3582,7 +3583,7 @@ build_user_type_conversion_1 (tree totype, tree ex
return NULL;
}
- cand = tourney (candidates);
+ cand = tourney (candidates, tf_warning_or_error);
if (cand == 0)
{
if (flags & LOOKUP_COMPLAIN)
@@ -3800,7 +3801,7 @@ perform_overload_resolution (tree fn,
*candidates = splice_viable (*candidates, pedantic, any_viable_p);
if (*any_viable_p)
- cand = tourney (*candidates);
+ cand = tourney (*candidates, tf_warning_or_error);
else
cand = NULL;
@@ -4106,7 +4107,7 @@ build_op_call_1 (tree obj, VEC(tree,gc) **args, ts
}
else
{
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (cand == 0)
{
if (complain & tf_error)
@@ -4584,7 +4585,7 @@ build_conditional_expr_1 (tree arg1, tree arg2, tr
}
return error_mark_node;
}
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (!cand)
{
if (complain & tf_error)
@@ -5113,7 +5114,7 @@ build_new_op_1 (enum tree_code code, int flags, tr
}
else
{
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (cand == 0)
{
if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
@@ -5140,7 +5141,7 @@ build_new_op_1 (enum tree_code code, int flags, tr
{
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. */
@@ -6383,7 +6384,7 @@ build_over_call (struct z_candidate *cand, int fla
{
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. */
@@ -7318,7 +7319,7 @@ build_new_method_call_1 (tree instance, tree fns,
}
else
{
- cand = tourney (candidates);
+ cand = tourney (candidates, complain);
if (cand == 0)
{
char *pretty_name;
@@ -8013,7 +8014,8 @@ add_warning (struct z_candidate *winner, struct z_
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 +8078,8 @@ static int
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 +8124,8 @@ static int
/* 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 +8287,18 @@ static int
{
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 +8315,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 +8361,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 +8372,7 @@ static struct z_candidate *
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 +8402,7 @@ static struct z_candidate *
&& !(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;
}