Hi,

On 07/15/2014 11:46 PM, Jason Merrill wrote:
You need to call resolve_nondeduced_context at some point. This doesn't seem to be the right place, since you also want to handle code like "if (foo<void>)". Maybe in resolve_address_of_overloaded_function just before the error?
Thanks, that helps (certainly resolve_nondeduced_context handles well the TEMPLATE_ID_EXPRs with which we are concerned, and, well, it's reassuring that decay_conversion calls it first).

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? I tested the below.

Thanks again,
Paolo.


Index: cp/call.c
===================================================================
--- cp/call.c   (revision 212576)
+++ cp/call.c   (working copy)
@@ -9241,6 +9241,8 @@ perform_implicit_conversion_flags (tree type, tree
   if (error_operand_p (expr))
     return error_mark_node;
 
+  expr = resolve_nondeduced_context (expr);
+
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
 
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 T > void foo ();
+
+bool b1 = !foo<void>;
+bool b2 = foo<void> ? true : false;
+
+void bar()
+{
+  if (foo<void>)
+    ;
+}

Reply via email to