The following (presumably valid) code causes segfault on trunk r220715 and 4.9.2: $ cat ./ice_sizeof.cc template<int N> struct array { int data[N]; }; template<template<typename> class... T1, typename T2> array<sizeof...(T1)> make_array(T1<T2> ...init) { return { 0 }; } template<typename T> struct S { T a; }; auto arr = make_array(S<int>{1}); ====================================================== miyuki@gcc-devel2:~/gcc/test/ice_sizeof$ ../../obj/gcc/cc1plus -std=c++11 ice_sizeof.cc &> bug_report.txt; cat bug_report.txt array<sizeof... (T1)> make_array(T1<T2>...) array<sizeof... (T1)> make_array(T1<T2>...) [with T1 = {S}; T2 = int] void __static_initialization_and_destruction_0(int, int) void _GLOBAL__sub_I_arr() Analyzing compilation unit ice_sizeof.cc: In instantiation of 'array<sizeof... (T1)> make_array(T1<T2>...) [with T1 = {S}; T2 = int]': ice_sizeof.cc:8:22: internal compiler error: tree check: expected class 'type', have 'declaration' (template_decl) in write_CV_qualifiers_for_type, at cp/mangle.c:2154 array<sizeof...(T1)> make_array(T1<T2> ...init) ^ 0xefd737 tree_class_check_failed(tree_node const*, tree_code_class, char const*, int, char const*) /home/miyuki/gcc/src/gcc/tree.c:9341 0x7c9e9b tree_class_check(tree_node*, tree_code_class, char const*, int, char const*) /home/miyuki/gcc/src/gcc/tree.h:2969 0x7c9e9b write_CV_qualifiers_for_type /home/miyuki/gcc/src/gcc/cp/mangle.c:2154 0x7d03b3 write_type /home/miyuki/gcc/src/gcc/cp/mangle.c:1876 0x7d07e1 write_type /home/miyuki/gcc/src/gcc/cp/mangle.c:2049 0x7cf5b8 write_template_arg /home/miyuki/gcc/src/gcc/cp/mangle.c:3158 0x7cfcb8 write_template_args /home/miyuki/gcc/src/gcc/cp/mangle.c:2546 0x7ced2a write_name /home/miyuki/gcc/src/gcc/cp/mangle.c:831 0x7d09e6 write_class_enum_type /home/miyuki/gcc/src/gcc/cp/mangle.c:2517 0x7d09e6 write_type /home/miyuki/gcc/src/gcc/cp/mangle.c:1974 0x7d2d04 write_bare_function_type /home/miyuki/gcc/src/gcc/cp/mangle.c:2440 0x7d7b39 mangle_decl_string /home/miyuki/gcc/src/gcc/cp/mangle.c:3411 0x7d7d77 get_mangled_id /home/miyuki/gcc/src/gcc/cp/mangle.c:3433 0x7d7d77 mangle_decl(tree_node*) /home/miyuki/gcc/src/gcc/cp/mangle.c:3478 0xefdd10 decl_assembler_name(tree_node*) /home/miyuki/gcc/src/gcc/tree.c:697 0x910d77 symtab_node::get_comdat_group_id() /home/miyuki/gcc/src/gcc/cgraph.h:207 0x910d77 analyze_functions /home/miyuki/gcc/src/gcc/cgraphunit.c:973 0x9120e5 symbol_table::finalize_compilation_unit() /home/miyuki/gcc/src/gcc/cgraphunit.c:2427 0x6f3037 cp_write_global_declarations() /home/miyuki/gcc/src/gcc/cp/decl2.c:4750 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. ====================================================== GCC 4.9.2 20141030 (Red Hat 4.9.2-5.ac1), i386, also crashes. GCC 4.8.2 20140120 (Red Hat 4.8.2-16) rejects the code with the following error: ./ice_sizeof.cc:8:20: error: template argument 1 is invalid array<sizeof...(T1)> make_array(T1<T2> ...init) clang-3.7 compiles the file without errors. Changing the declaration to "auto make_array_ice(T1<T2> ...init) -> array<sizeof...(T1)>" does not change the behavior, but "auto make_array_ice(T1<T2> ...init) -> array<sizeof...(init)>" gets compiled without errors by all 3 mentioned versions of g++.
A few more comments. I wrote that GCC 5.0 segfaults. That's actually not true, I could not reproduce segfault on checked builds (only release version of 4.9.2), but never the less it's still ICE. So, here is a bit more minimized example: $ cat ice_sizeof.cc template<int> struct S { }; template<template<int> class... T, int N> S<sizeof...(T)> foo(T<N>...); auto x = foo(S<2>{}); ========================================== The problem occurs during name mangling. I defined #define DEBUG_MANGLE 1 The debug output (before ICE happens) ends with this: identifier : S ++ add_substitution (template_decl at 0x7fb804560100) ++ substitutions S-1_ = foo (template_decl at 0x7fb804560400) S0_ = S (template_decl at 0x7fb804560100) template-arg : integer_cst (0x7fb80441c570) type : integer_type (0x7fb8043fe690) ++ find_substitution (integer_type at 0x7fb8043fe690) bare-function-type : function_type (0x7fb804552c78) type : record_type (0x7fb804552930) ++ find_substitution (record_type at 0x7fb804552930) name : type_decl (0x7fb80454e5f0) unscoped-template-name : template_decl (0x7fb804560100) ++ find_substitution (template_decl at 0x7fb804560100) substitution : template-args : tree_vec (0x7fb80455cca0) template-arg : sizeof_expr (0x7fb80455cc60) type : type_pack_expansion (0x7fb804552888) ++ find_substitution (type_pack_expansion at 0x7fb804552888) type : template_decl (0x7fb804560280) ++ find_substitution (template_decl at 0x7fb804560280) If I understand correctly, tree_class_check fails when we attempt to mangle the argument of sizeof...(T). It is (probably) represented through parameter pack expansion (sizeof...(T) must have the same value as the number of parameters in the pack "T<N>..."), which in turn depends on substitution of template template parameter T. Template template parameters are represented using TEMPLATE_DECL: ... else if (code == TEMPLATE_DECL) /* A template appearing as a template arg is a template template arg. */ write_template_template_arg (node); ... And write_CV_qualifiers_for_type rejects it.
I can confirm the ICE.
For the record: a patch for this PR https://gcc.gnu.org/ml/gcc-patches/2015-02/msg01067.html
Author: paolo Date: Tue Jul 14 22:36:50 2015 New Revision: 225793 URL: https://gcc.gnu.org/viewcvs?rev=225793&root=gcc&view=rev Log: /cp 2015-07-14 Andrea Azzarone <azzaronea@gmail.com> PR c++/65071 * parser.c (cp_parser_sizeof_pack): Also consider template template parameters. /testsuite 2015-07-14 Andrea Azzarone <azzaronea@gmail.com> PR c++/65071 * g++.dg/cpp0x/vt-65071.C: New. Added: trunk/gcc/testsuite/g++.dg/cpp0x/vt-65071.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/parser.c trunk/gcc/testsuite/ChangeLog
Fixed.