Patchwork [C++,Patch/RFC] PR 50961

login
register
mail settings
Submitter Paolo Carlini
Date July 17, 2014, 9:28 a.m.
Message ID <53C7973F.102@oracle.com>
Download mbox | patch
Permalink /patch/371036/
State New
Headers show

Comments

Paolo Carlini - July 17, 2014, 9:28 a.m.
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.

////////////////////////
Jason Merrill - July 17, 2014, 4:04 p.m.
OK.

Jason

Patch

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