call.c (build_builtin_candidate): Don't set LOOKUP_ONLYCONVERTING if we're contextually converting to bool.

* 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.

From-SVN: r151114
This commit is contained in:
Jason Merrill 2009-08-26 00:35:26 -04:00 committed by Jason Merrill
parent 7919d7b442
commit 1dad57e65d
5 changed files with 68 additions and 4 deletions

View File

@ -1,5 +1,10 @@
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.

View File

@ -1778,7 +1778,14 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
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)
{
@ -3593,7 +3600,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
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. */

View File

@ -4270,8 +4270,8 @@ condition_conversion (tree expr)
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;
}

View File

@ -1,5 +1,6 @@
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>

View File

@ -0,0 +1,50 @@
// 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 "" }
}