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>)
+ ;
+}