diff mbox

[C++,Patch/RFC] PR 70572 ("[4.9/5/6/7 Regression] ICE on code with decltype (auto) on x86_64-linux-gnu in digest_init_r")

Message ID 573EF24F.2000205@oracle.com
State New
Headers show

Commit Message

Paolo Carlini May 20, 2016, 11:17 a.m. UTC
Hi,

On 19/05/2016 15:58, Jason Merrill wrote:
> On 05/18/2016 07:13 PM, Paolo Carlini wrote:
>> +      error ("cannot declare variable %q+D with function type", decl);
>
> I think the error message would be more helpful if it mentioned 
> decltype(auto), maybe
>
> "initializer for %<decltype(auto) %D%> has function type, did you 
> forget the %<()%>?", DECL_NAME (decl)
>
> (or some other way to print the variable type as declared rather than 
> as deduced).

The below passes testing. There are a few minor changes wrt your 
suggestions (I think we want & as hint; spacing consistent with 
typeck2.c; DECL_NAME doesn't seem necessary). I wondered if we want to 
tighten the condition consistently with the wording of the error 
message, thus patchlet *2 below, which of course also passes testing.

Thanks,
Paolo.

///////////////////////

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 236496)
+++ cp/decl.c	(working copy)
@@ -6609,6 +6609,14 @@ cp_finish_decl (tree decl, tree init, bool init_co
                                                    adc_variable_type);
       if (type == error_mark_node)
 	return;
+      if (TREE_CODE (type) == FUNCTION_TYPE
+	  && TREE_CODE (TREE_TYPE (d_init)) == FUNCTION_TYPE)
+	{
+	  error ("initializer for %<decltype(auto) %D%> has function type "
+		 "(did you forget the %<&%> ?)", decl);
+	  TREE_TYPE (decl) = error_mark_node;
+	  return;
+	}
       cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
     }
 
Index: testsuite/g++.dg/cpp1y/auto-fn31.C
===================================================================
--- testsuite/g++.dg/cpp1y/auto-fn31.C	(revision 0)
+++ testsuite/g++.dg/cpp1y/auto-fn31.C	(working copy)
@@ -0,0 +1,7 @@
+// PR c++/70572
+// { dg-do compile { target c++14 } }
+
+void foo ()
+{
+  decltype (auto) a = foo;  // { dg-error "initializer" }
+}

Comments

Jason Merrill May 20, 2016, 3:24 p.m. UTC | #1
On 05/20/2016 07:17 AM, Paolo Carlini wrote:
> The below passes testing. There are a few minor changes wrt your
> suggestions (I think we want & as hint;

I disagree; if what the user wanted was a function pointer, there's no 
reason to use decltype(auto) over plain auto.  Much more likely that 
they meant to capture the (possibly reference) result of a call.

> spacing consistent with
> typeck2.c; DECL_NAME doesn't seem necessary). I wondered if we want to
> tighten the condition consistently with the wording of the error
> message, thus patchlet *2 below, which of course also passes testing.

No, I don't think there's any way to deduce function type without the 
initializer having function type.

So, the first patch is OK with the message changed to ().

Jason
Paolo Carlini May 20, 2016, 3:39 p.m. UTC | #2
Hi,

On 20/05/2016 17:24, Jason Merrill wrote:
> On 05/20/2016 07:17 AM, Paolo Carlini wrote:
>> The below passes testing. There are a few minor changes wrt your
>> suggestions (I think we want & as hint;
>
> I disagree; if what the user wanted was a function pointer, there's no 
> reason to use decltype(auto) over plain auto.  Much more likely that 
> they meant to capture the (possibly reference) result of a call.
... ok, if you are sure that the user (ok, novice programmer) will not 
be puzzled when he will see that decltype (auto) a = foo () also does 
not work... but I agree hints are hints, will never be 100% correct and 
informative...
>> spacing consistent with
>> typeck2.c; DECL_NAME doesn't seem necessary). I wondered if we want to
>> tighten the condition consistently with the wording of the error
>> message, thus patchlet *2 below, which of course also passes testing.
>
> No, I don't think there's any way to deduce function type without the 
> initializer having function type.
>
> So, the first patch is OK with the message changed to ().
Ok.

Paolo.
Paolo Carlini June 8, 2016, 8:21 a.m. UTC | #3
.. shall we fix this in gcc-6-branch too or not? It's just an ICE on 
invalid but we don't emit any diagnostic before the crash.

Thanks,
Paolo.
Jason Merrill June 14, 2016, 7:34 p.m. UTC | #4
On Wed, Jun 8, 2016 at 4:21 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> .. shall we fix this in gcc-6-branch too or not? It's just an ICE on invalid
> but we don't emit any diagnostic before the crash.

Sure, it should be safe enough.

Jason
diff mbox

Patch

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 236496)
+++ cp/decl.c	(working copy)
@@ -6609,6 +6609,13 @@  cp_finish_decl (tree decl, tree init, bool init_co
                                                    adc_variable_type);
       if (type == error_mark_node)
 	return;
+      if (TREE_CODE (type) == FUNCTION_TYPE)
+	{
+	  error ("initializer for %<decltype(auto) %D%> has function type "
+		 "(did you forget the %<&%> ?)", decl);
+	  TREE_TYPE (decl) = error_mark_node;
+	  return;
+	}
       cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
     }
 
Index: testsuite/g++.dg/cpp1y/auto-fn31.C
===================================================================
--- testsuite/g++.dg/cpp1y/auto-fn31.C	(revision 0)
+++ testsuite/g++.dg/cpp1y/auto-fn31.C	(working copy)
@@ -0,0 +1,7 @@ 
+// PR c++/70572
+// { dg-do compile { target c++14 } }
+
+void foo ()
+{
+  decltype (auto) a = foo;  // { dg-error "initializer" }
+}