aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-08-26 00:35:26 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-08-26 00:35:26 -0400
commit1dad57e65d9539eccc652dbb42b5574db72bb3fc (patch)
tree221363f432b4f3bce972f15059e31d770a04f532 /gcc
parent7919d7b4422cefaa7768d576a73bcf96a6efd6cb (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/cp/call.c12
-rw-r--r--gcc/cp/typeck.c4
-rw-r--r--gcc/testsuite/ChangeLog1
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/explicit3.C50
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 "" }
+}