2009-08-26 Jason Merrill <jason@redhat.com>
+ * call.c (build_builtin_candidate): Don't set LOOKUP_ONLYCONVERTING
+ if we're contextually converting to bool.
+ (build_conditional_expr): Likewise.
+ * typeck.c (condition_conversion): Likewise.
+
* call.c (build_conditional_expr): Fix logic errors.
(build_new_op): Remove dead COND_EXPR handling.
num_convs = args[2] ? 3 : (args[1] ? 2 : 1);
convs = alloc_conversions (num_convs);
- flags |= LOOKUP_ONLYCONVERTING;
+
+ /* TRUTH_*_EXPR do "contextual conversion to bool", which means explicit
+ conversion ops are allowed. We handle that here by just checking for
+ boolean_type_node because other operators don't ask for it. COND_EXPR
+ also does contextual conversion to bool for the first operand, but we
+ handle that in build_conditional_expr, and type1 here is operand 2. */
+ if (type1 != boolean_type_node)
+ flags |= LOOKUP_ONLYCONVERTING;
for (i = 0; i < 2; ++i)
{
The first expression is implicitly converted to bool (clause
_conv_). */
- arg1 = perform_implicit_conversion (boolean_type_node, arg1, complain);
+ arg1 = perform_implicit_conversion_flags (boolean_type_node, arg1, complain,
+ LOOKUP_NORMAL);
/* If something has already gone wrong, just pass that fact up the
tree. */
tree t;
if (processing_template_decl)
return expr;
- t = perform_implicit_conversion (boolean_type_node, expr,
- tf_warning_or_error);
+ t = perform_implicit_conversion_flags (boolean_type_node, expr,
+ tf_warning_or_error, LOOKUP_NORMAL);
t = fold_build_cleanup_point_expr (boolean_type_node, t);
return t;
}
2009-08-26 Jason Merrill <jason@redhat.com>
+ * g++.dg/cpp0x/explicit3.C: New.
* g++.dg/overload/cond2.C: New.
2009-08-25 Kaz Kojima <kkojima@gcc.gnu.org>
--- /dev/null
+// Test for "contextually converted to bool"
+// { dg-options "-std=c++0x" }
+
+struct A
+{
+ explicit operator bool();
+};
+
+void f (bool);
+
+struct B
+{
+ bool b;
+};
+
+struct C
+{
+ operator int();
+};
+
+struct D
+{
+ operator int();
+};
+
+int main()
+{
+ A a; C c; D d;
+ // These contexts use an explicit bool conversion.
+ if (a) {}
+ for (; a; ) {}
+ do {} while (a);
+ while (a) {}
+ a ? 1 : 0;
+ a || true;
+ a && true;
+ !a;
+
+ a ? c : 1;
+ a ? c : d;
+
+ // These do not.
+ switch (a); // { dg-error "" }
+ bool b = a; // { dg-error "" }
+ f(a); // { dg-error "" }
+ B b2 = { a }; // { dg-error "" }
+ a + true; // { dg-message "" }
+ b ? a : true; // { dg-message "" }
+ a ? a : true; // { dg-message "" }
+}