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