Checking for a flexible array in a union is currently done by grokdeclarator, so it wasn't being caught after substitution. I didn't see a good place to handle it for both cases, and it's small enough, so I just copied it over.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit e63bd3e7471152b3c39cbfc58e735e3efeb458b7 Author: Jason Merrill <ja...@redhat.com> Date: Mon Apr 9 17:24:19 2018 -0400 PR c++/85285 - ICE with flexible array after substitution. * pt.c (instantiate_class_template_1): Check for flexible array in union. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index db3d7e38d85..76e546cdeaa 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10904,6 +10904,14 @@ instantiate_class_template_1 (tree type) cxx_incomplete_type_error (r, rtype); TREE_TYPE (r) = error_mark_node; } + else if (TREE_CODE (rtype) == ARRAY_TYPE + && TYPE_DOMAIN (rtype) == NULL_TREE + && (TREE_CODE (type) == UNION_TYPE + || TREE_CODE (type) == QUAL_UNION_TYPE)) + { + error ("flexible array member %qD in union", r); + TREE_TYPE (r) = error_mark_node; + } } /* If it is a TYPE_DECL for a class-scoped ENUMERAL_TYPE, diff --git a/gcc/testsuite/g++.dg/ext/flexary30.C b/gcc/testsuite/g++.dg/ext/flexary30.C new file mode 100644 index 00000000000..59b7587594c --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary30.C @@ -0,0 +1,8 @@ +// PR c++/85285 + +template<typename T> union A +{ + T x; // { dg-error "flexible array" } +}; + +A<int[]> a;