]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
call.c (build_builtin_candidate): Don't set LOOKUP_ONLYCONVERTING if we're contextual...
authorJason Merrill <jason@redhat.com>
Wed, 26 Aug 2009 04:35:26 +0000 (00:35 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 26 Aug 2009 04:35:26 +0000 (00:35 -0400)
* 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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/explicit3.C [new file with mode: 0644]

index e7f45008f1386ae2e990411db50295ade01f8955..1bd31857e3bf4609879abfaebfe82fe6db5de70d 100644 (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.
 
index 8dc6d2ae31d24eb56acf9c27ab3441bde643d55c..f4b0497b7f95c61fc01fe0cc67f14d6dce2adc3d 100644 (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.  */
index de42af409da04a1b8bee434be0cad85be49f6894..53165b38dc30aa77e8813e086870a872eacaaf1d 100644 (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;
 }
index d465ac203778a256d1732c5891488a5f622a4532..c2236d54f19cdca5f3ce695a10a0fa943f8bfd3b 100644 (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>
diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit3.C b/gcc/testsuite/g++.dg/cpp0x/explicit3.C
new file mode 100644 (file)
index 0000000..cd37a15
--- /dev/null
@@ -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 "" }
+}