diff options
author | Jason Merrill <jason@redhat.com> | 2009-08-26 00:35:26 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-08-26 00:35:26 -0400 |
commit | 1dad57e65d9539eccc652dbb42b5574db72bb3fc (patch) | |
tree | 221363f432b4f3bce972f15059e31d770a04f532 /gcc | |
parent | 7919d7b4422cefaa7768d576a73bcf96a6efd6cb (diff) | |
download | gcc-1dad57e65d9539eccc652dbb42b5574db72bb3fc.zip gcc-1dad57e65d9539eccc652dbb42b5574db72bb3fc.tar.gz gcc-1dad57e65d9539eccc652dbb42b5574db72bb3fc.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/call.c | 12 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/explicit3.C | 50 |
5 files changed, 68 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e7f4500..1bd3185 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 8dc6d2a..f4b0497 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index de42af4..53165b3 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d465ac2..c2236d5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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> diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit3.C b/gcc/testsuite/g++.dg/cpp0x/explicit3.C new file mode 100644 index 0000000..cd37a15 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/explicit3.C @@ -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 "" } +} |