Hi,

On 07/17/2014 02:40 AM, Jason Merrill wrote:
On 07/16/2014 12:39 AM, Paolo Carlini wrote:
In practice, both for the original testcase and for a conditional (and
in more cases, eg conditional expressions), what happens is that
perform_implicit_conversion_flags is called, which, when
implicit_conversion fails, calls instantiate_type (and then
resolve_address_of_overloaded_function) only to get a good error
message. Thus, would it make sense to use resolve_nondeduced_context in
perform_implicit_conversion_flags itself?!? Conservatively, only when
the target type is a boolean_type_node, maybe?
How about in standard_conversion in the type_unknown_p case after we've checked for pointer-to(-member)-function?
Ah, I noticed that place a few days ago, when I didn't know about resolve_nondeduced_context, then I completely forgot about it...

The below passes testing.

Thanks!
Paolo.

////////////////////////
Index: cp/call.c
===================================================================
--- cp/call.c   (revision 212742)
+++ cp/call.c   (working copy)
@@ -1107,14 +1107,22 @@ standard_conversion (tree to, tree from, tree expr
   to = strip_top_quals (to);
   from = strip_top_quals (from);
 
-  if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
-      && expr && type_unknown_p (expr))
+  if (expr && type_unknown_p (expr))
     {
-      tsubst_flags_t tflags = tf_conv;
-      expr = instantiate_type (to, expr, tflags);
-      if (expr == error_mark_node)
-       return NULL;
-      from = TREE_TYPE (expr);
+      if (TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
+       {
+         tsubst_flags_t tflags = tf_conv;
+         expr = instantiate_type (to, expr, tflags);
+         if (expr == error_mark_node)
+           return NULL;
+         from = TREE_TYPE (expr);
+       }
+      else if (TREE_CODE (to) == BOOLEAN_TYPE)
+       {
+         /* Necessary for eg, TEMPLATE_ID_EXPRs (c++/50961).  */
+         expr = resolve_nondeduced_context (expr);
+         from = TREE_TYPE (expr);
+       }
     }
 
   fcode = TREE_CODE (from);
Index: testsuite/g++.dg/template/operator13.C
===================================================================
--- testsuite/g++.dg/template/operator13.C      (revision 0)
+++ testsuite/g++.dg/template/operator13.C      (working copy)
@@ -0,0 +1,12 @@
+// PR c++/50961
+
+template < class > void foo ();
+
+bool b1 = !foo<void>;
+bool b2 = foo<void> ? true : false;
+
+void bar()
+{
+  if (foo<void>)
+    ;
+}

Reply via email to