flags |= LOOKUP_NO_CONVERSION;
if (BRACE_ENCLOSED_INITIALIZER_P (expr))
flags |= LOOKUP_NO_NARROWING;
+ /* Prevent add_candidates from treating a non-strictly viable candidate
+ as unviable. */
+ complain |= tf_conv;
/* It's OK to bind a temporary for converting constructor arguments, but
not in converting the return value of a conversion operator. */
stopped at the first bad conversion). Add the function to BAD_FNS
to fully reconsider later if we don't find any strictly viable
candidates. */
- bad_fns = lookup_add (fn, bad_fns);
- *candidates = (*candidates)->next;
+ if (complain & (tf_error | tf_conv))
+ {
+ bad_fns = lookup_add (fn, bad_fns);
+ *candidates = (*candidates)->next;
+ }
+ else
+ /* But if we're in a SFINAE context, just mark this candidate as
+ unviable outright and avoid potentially reconsidering it.
+ This is safe to do because in a SFINAE context, performing a bad
+ conversion is always an error (even with -fpermissive), so a
+ non-strictly viable candidate is effectively unviable anyway. */
+ cand->viable = 0;
}
}
if (which == non_templates && !seen_perfect)
--- /dev/null
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-fpermissive" }
+
+struct A {
+ A(int*, int);
+};
+
+void f(A);
+
+int main() {
+ const int n = 0;
+ f({&n, 42}); // { dg-warning "invalid conversion from 'const int\\*' to 'int\\*'" }
+}