https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92625
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org Target Milestone|9.3 |8.4 Summary|[9/10 Regression] Internal |[8/9/10 Regression] |compiler error accessing |Internal compiler error |element in static constexpr |accessing element in static |char array in template |constexpr char array in |class using alias |template class using alias --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Though, with a small modification it started with r221328. template <typename T> struct G { using C = char; static constexpr C my_array[1] = ""; }; void work () { G<double>::my_array[1]; } This ICEs because in tsubst_copy we do for STRING_CST: 16647 /* Instantiate any typedefs in the type. */ 16648 tree type = tsubst (TREE_TYPE (t), args, complain, in_decl); 16649 r = fold_convert (type, t); 16650 gcc_assert (TREE_CODE (r) == code); For other codes handled by this like INTEGER_CST, REAL_CST and COMPLEX_CST, the assertion is meaningful, but for STRING_CSTs fold_convert doesn't really create a new STRING_CST with different type. Both types are C[1], just the C is different tree between the two. So, shall we just not do this assertion (say gcc_assert (code == STRING_CST || TREE_CODE (r) == code); and is it fine if we return a NOP_EXPR? I guess it could change something for lvalues, with say ADDR_EXPR of a STRING_CST being valid, but ADDR_EXPR of NOP_EXPR of STRING_CST not valid. Or shall we build a new STRING_CST with the new type if the type is different? Something else?