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 573C8ED1.40608@oracle.com
State New
Headers show

Commit Message

Paolo Carlini May 18, 2016, 3:48 p.m. UTC
Hi,

this issue should be easy to fix. Broken code like:

void foo ()
{
   decltype (auto) a = foo;
}

triggers the gcc_assert in digest_init_r:

   /* Come here only for aggregates: records, arrays, unions, complex 
numbers
      and vectors.  */
   gcc_assert (TREE_CODE (type) == ARRAY_TYPE
           || VECTOR_TYPE_P (type)
           || TREE_CODE (type) == RECORD_TYPE
           || TREE_CODE (type) == UNION_TYPE
           || TREE_CODE (type) == COMPLEX_TYPE);

because of course TREE_CODE (type) == FUNCTION_TYPE, none of the above. 
I said should be easy to fix because in fact convert_for_initialization 
is perfectly able to handle these cases and emit proper diagnostic, if 
called. What shall we do then? The patchlet below passes testing but we 
could also relax the gcc_assert itself, include FUNCTION_TYPE 
with/without checking cxx_dialect >= cxx14. We could drop the latter 
check in my patchlet. Or something else entirely.

Thanks!
Paolo.

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

Comments

Jason Merrill May 18, 2016, 9:13 p.m. UTC | #1
On 05/18/2016 11:48 AM, Paolo Carlini wrote:
> Hi,
>
> this issue should be easy to fix. Broken code like:
>
> void foo ()
> {
>   decltype (auto) a = foo;
> }
>
> triggers the gcc_assert in digest_init_r:
>
>   /* Come here only for aggregates: records, arrays, unions, complex
> numbers
>      and vectors.  */
>   gcc_assert (TREE_CODE (type) == ARRAY_TYPE
>           || VECTOR_TYPE_P (type)
>           || TREE_CODE (type) == RECORD_TYPE
>           || TREE_CODE (type) == UNION_TYPE
>           || TREE_CODE (type) == COMPLEX_TYPE);
>
> because of course TREE_CODE (type) == FUNCTION_TYPE, none of the above.
> I said should be easy to fix because in fact convert_for_initialization
> is perfectly able to handle these cases and emit proper diagnostic, if
> called. What shall we do then? The patchlet below passes testing but we
> could also relax the gcc_assert itself, include FUNCTION_TYPE
> with/without checking cxx_dialect >= cxx14. We could drop the latter
> check in my patchlet. Or something else entirely.
>
> Thanks!
> Paolo.
>
> ////////////////////////

Shouldn't we have complained about declaring a variable with function 
type before we get here?

Jason
diff mbox

Patch

Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c	(revision 236400)
+++ cp/typeck2.c	(working copy)
@@ -1074,10 +1074,14 @@  digest_init_r (tree type, tree init, bool nested,
 	}
     }
 
-  /* Handle scalar types (including conversions) and references.  */
+  /* Handle scalar types (including conversions) and references.
+     Also handle cases of erroneous C++14 code involving function types
+     like (c++/70572): void foo () { decltype (auto) a = foo; }
+     and get a proper error message from convert_for_initialization.  */
   if ((TREE_CODE (type) != COMPLEX_TYPE
        || BRACE_ENCLOSED_INITIALIZER_P (init))
-      && (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE))
+      && (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE
+	  || (TREE_CODE (type) == FUNCTION_TYPE && cxx_dialect >= cxx14)))
     {
       if (nested)
 	flags |= LOOKUP_NO_NARROWING;
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 "cannot convert" }
+}