Hi! >From N2965 it is unclear to me what should the trait do on classes with incomplete types, but given that __bases already returns an empty pack, this patch does the same for __direct_bases.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2018-04-03 Jakub Jelinek <ja...@redhat.com> PR c++/85146 * semantics.c (calculate_direct_bases): Return empty vector if TYPE_BINFO is NULL. Formatting fixes. * g++.dg/ext/bases3.C: New test. --- gcc/cp/semantics.c.jj 2018-03-30 20:38:03.370202169 +0200 +++ gcc/cp/semantics.c 2018-04-03 09:32:38.462091604 +0200 @@ -3898,36 +3898,26 @@ calculate_direct_bases (tree type) complete_type (type); - if (!NON_UNION_CLASS_TYPE_P (type)) + if (!NON_UNION_CLASS_TYPE_P (type) || !TYPE_BINFO (type)) return make_tree_vec (0); base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type)); /* Virtual bases are initialized first */ for (i = 0; base_binfos->iterate (i, &binfo); i++) - { - if (BINFO_VIRTUAL_P (binfo)) - { - vec_safe_push (vector, binfo); - } - } + if (BINFO_VIRTUAL_P (binfo)) + vec_safe_push (vector, binfo); /* Now non-virtuals */ for (i = 0; base_binfos->iterate (i, &binfo); i++) - { - if (!BINFO_VIRTUAL_P (binfo)) - { - vec_safe_push (vector, binfo); - } - } - + if (!BINFO_VIRTUAL_P (binfo)) + vec_safe_push (vector, binfo); bases_vec = make_tree_vec (vector->length ()); for (i = 0; i < vector->length (); ++i) - { - TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]); - } + TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]); + return bases_vec; } --- gcc/testsuite/g++.dg/ext/bases3.C.jj 2018-04-03 09:39:49.547038799 +0200 +++ gcc/testsuite/g++.dg/ext/bases3.C 2018-04-03 09:39:28.301041301 +0200 @@ -0,0 +1,13 @@ +// PR c++/85146 +// { dg-do compile { target c++11 } } + +template<typename...> struct A {}; + +template<typename T> struct B +{ + typedef A<__direct_bases(T)...> C; +}; + +struct X; + +B<X> b; Jakub