The following test case causes internal compiler error: #include <type_traits> #include <vector> struct A { template <typename> static std::false_type fn(...); }; template <class T> struct B : public A { using fn = decltype(fn<T>(0)); using type = typename std::conditional<fn::value, std::true_type, std::false_type>::type; }; int main(){ static_assert(B<std::vector<int>>::type::value, "assertion failed"); } If you change either of them, the bug will go away: - Move A::fn() out of its structure thus make "B : public A" inheritance unnecessary - Rename B::fn to something else, like B::fn_alias. The issue first appeared in 8.1 (7.4 is fine) and still occurs with 10.0.0 20190908. Error messages: GCC 10.0: internal compiler error: tree check: expected class 'type', have 'exceptional' (error_mark) in equate_type_number_to_die, at dwarf2out.c:5782 9.2 - 8.1: internal compiler error: in is_base_type, at dwarf2out.c:12987 Related issue: Bug 87772 (though I don't know whether the path is the same which led to a similar ICE message).
Confirmed. The struct B type has a member <type_decl 0x7ffff5e2eed8 type type <error_mark 0x7ffff680de40> asm_written external nonlocal suppress-debug decl_6 VOID t.C:12:9 align:8 warn_if_not_align:0 context <record_type 0x7ffff60a8888 B> result <typename_type 0x7ffff60a8150 type VOID align:8 warn_if_not_align:0 symtab:0 alias-set -1 structural-equality context <record_type 0x7ffff6098f18 conditional> fullname <identifier_node 0x7ffff6826f00 type type <error_mark 0x7ffff680de40> normal local bindings <0x7ffff5d40be0>> chain <type_decl 0x7ffff5e2e000 type>> > which we don't expect. Frontend issue. It should have raised an error here? > clang++ t.C t.C:16:3: error: static_assert failed due to requirement 'B<std::vector<int> >::type::value' "assertion failed" static_assert(B<std::vector<int>>::type::value, "assertion failed"); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. The ICE with GCC 9 is the same note DECL_ORGINAL_TYPE is "sane" (well, 'void'). And dwarf2out has 25421 if (DECL_ORIGINAL_TYPE (decl)) 25422 { 25423 type = DECL_ORIGINAL_TYPE (decl); 25424 if (type == error_mark_node) 25425 return; 25426 25427 gcc_assert (type != TREE_TYPE (decl)); 25428 equate_type_number_to_die (TREE_TYPE (decl), type_die); so it checks DECL_ORIGINAL_TYPE but then uses TREE_TYPE which actually is error_mark_node.
Started with r251438.
template <bool> struct A; template <typename = int> struct B; struct C { template <typename> static int c (); }; template <class T> struct D : C { using c = decltype (c<T>); using E = typename A<c::g>::E; }; D<B<>> g; Without -g this is a accepts-invalid.
GCC 8.4.0 has been released, adjusting target milestone.
Slightly more reduced testcase: template <bool> struct A; struct C { template <typename> static int c (); }; template <class T> struct D : C { using c = decltype (c<T>); using E = A<c::g>; }; D<int> g;
Valid variant: template <bool> struct A; struct B { static constexpr bool g = false; }; struct C { template <typename> static B c (); }; template <class T> struct D : C { using c = decltype (c<T>()); using E = A<c::g>; }; D<int> g; This is a complex interaction of issues. Looking up c<T> in the definition of D::c finds C::c, OK. Looking up c in the definition of E finds D::c, which is depedent, OK. Since the alias is not dependent, we strip it from the template argument, leaving using E = A<decltype(c<T>())>; where 'c' still refers to C::c. But instantiating E looks up 'c' again and finds D::c, which isn't a function, so things go wrong. I think the bug here is looking up 'c' in D at instantiation time; the declaration we found before is not dependent.
Created attachment 50632 [details] near fix This seemed like a fix, but it breaks the modules/merge-8 testcase, and debugging that is being slow.
GCC 8 branch is being closed.
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:f07edb5d7f3e77218ec846a9382f7c1d23e67b71 commit r12-1272-gf07edb5d7f3e77218ec846a9382f7c1d23e67b71 Author: Jason Merrill <jason@redhat.com> Date: Fri Apr 16 11:13:40 2021 -0400 c++: alias with same name as base fn [PR91706] This is a bit complex. Looking up c<T> in the definition of D::c finds C::c, OK. Looking up c in the definition of E finds D::c, OK. Since the alias is not dependent, we strip it from the template argument, leaving using E = A<decltype(c<T>())>; where 'c' still refers to C::c. But instantiating E looks up 'c' again and finds D::c, which isn't a function, and sadness ensues. I think the bug here is looking up 'c' in D at instantiation time; the declaration we found before is not dependent. This seems to happen because baselink_for_fns gets BASELINK_BINFO wrong; it is supposed to be the base where lookup found the functions, C in this case. gcc/cp/ChangeLog: PR c++/91706 * semantics.c (baselink_for_fns): Fix BASELINK_BINFO. gcc/testsuite/ChangeLog: PR c++/91706 * g++.dg/template/lookup17.C: New test.
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:1a98f830332e5a623278aaeea39c2a88177b2a9a commit r12-1273-g1a98f830332e5a623278aaeea39c2a88177b2a9a Author: Jason Merrill <jason@redhat.com> Date: Fri Apr 16 13:52:02 2021 -0400 c++: preserve BASELINK from lookup [PR91706] In the earlier patch for PR91706 I fixed the BASELINK built by baselink_for_fns, but since we already had one from lookup, we should keep that one around instead of stripping it. The removed hunk in get_class_binding was a wierdly large amount of code to decide whether to pull out BASELINK_FUNCTIONS. gcc/cp/ChangeLog: PR c++/91706 * name-lookup.c (get_class_binding): Keep a BASELINK. (set_inherited_value_binding_p): Adjust. * lambda.c (is_lambda_ignored_entity): Adjust. * pt.c (lookup_template_function): Copy a BASELINK before modifying it.
The releases/gcc-11 branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:46c1a9f6d03ab444b42c41067597e3fbfba38486 commit r11-8524-g46c1a9f6d03ab444b42c41067597e3fbfba38486 Author: Jason Merrill <jason@redhat.com> Date: Fri Apr 16 11:13:40 2021 -0400 c++: alias with same name as base fn [PR91706] This is a bit complex. Looking up c<T> in the definition of D::c finds C::c, OK. Looking up c in the definition of E finds D::c, OK. Since the alias is not dependent, we strip it from the template argument, leaving using E = A<decltype(c<T>())>; where 'c' still refers to C::c. But instantiating E looks up 'c' again and finds D::c, which isn't a function, and sadness ensues. I think the bug here is looking up 'c' in D at instantiation time; the declaration we found before is not dependent. This seems to happen because baselink_for_fns gets BASELINK_BINFO wrong; it is supposed to be the base where lookup found the functions, C in this case. gcc/cp/ChangeLog: PR c++/91706 * semantics.c (baselink_for_fns): Fix BASELINK_BINFO. gcc/testsuite/ChangeLog: PR c++/91706 * g++.dg/template/lookup17.C: New test.
Fixed for 11.2/12 so far. Is there interest in fixing this on the 9/10 branches?
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:6816a44dfe1b5fa9414490a18a4aa723b6f38f18 commit r12-1543-g6816a44dfe1b5fa9414490a18a4aa723b6f38f18 Author: Jason Merrill <jason@redhat.com> Date: Wed Jun 16 16:09:59 2021 -0400 c++: static memfn from non-dependent base [PR101078] After my patch for PR91706, or before that with the qualified call, tsubst_baselink returned a BASELINK with BASELINK_BINFO indicating a base of a still-dependent derived class. We need to look up the relevant base binfo in the substituted class. PR c++/101078 PR c++/91706 gcc/cp/ChangeLog: * pt.c (tsubst_baselink): Update binfos in non-dependent case. gcc/testsuite/ChangeLog: * g++.dg/template/access39.C: New test.
GCC 9 branch is being closed
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
Fixed in GCC 11.2