https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92009
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|ASSIGNED |NEW CC| |jason at gcc dot gnu.org Assignee|jakub at gcc dot gnu.org |unassigned at gcc dot gnu.org --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, cxx_fold_indirect_ref is called with void * as type and &_ZTIi as op0 (with some casts that are skipped). Previously, before r276563, it would fail, because for FIELD_DECLs we would check if the FIELD_DECL's type is similar to type (it is not) and punt. _ZTIi has type __fundamental_type_info_pseudo_2, which is a struct containing (an anonymous) FIELD_DECL with __type_info_pseudo_0 type, which is again a struct containing some FIELD_DECLs, an anynymous FIELD_DECL with void * type as the first element. So, the r276563 code in this case will recurse and find the void * type in there. The ICE later on is that constexpr.c code when evaluating _ZTIi VAR_DECL with that __fundamental_type_info_pseudo_2 calls 4758 if (COMPLETE_TYPE_P (TREE_TYPE (t)) 4759 && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false)) on it, and is_really_empty_class has: 8449 for (binfo = TYPE_BINFO (type), i = 0; 8450 BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) 8451 if (!is_really_empty_class (BINFO_TYPE (base_binfo), ignore_vptr)) 8452 return false; While __fundamental_type_info_pseudo_2 has CLASS_TYPE_P flag set (created through get_tinfo_desc 1461 /* Create the pseudo type. */ 1462 tree pseudo_type = make_class_type (RECORD_TYPE); 1463 /* Pass the fields chained in reverse. */ 1464 finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE); 1465 CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type; it has NULL TYPE_BINFO. So, shall is_really_empty_class not go through TYPE_BINFO if it is NULL, or shall get_tinfo_desc fill in TYPE_BINFO, something else? E.g. following (without needed reindentation) fixes the ICE: --- gcc/cp/class.c.jj 2019-10-05 09:36:39.244674589 +0200 +++ gcc/cp/class.c 2019-10-07 12:04:04.555012116 +0200 @@ -8446,6 +8446,7 @@ is_really_empty_class (tree type, bool i if (!ignore_vptr && TYPE_CONTAINS_VPTR_P (type)) return false; + if (TYPE_BINFO (type)) for (binfo = TYPE_BINFO (type), i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) if (!is_really_empty_class (BINFO_TYPE (base_binfo), ignore_vptr)) Another thing I'm worried about, namespace std { class type_info {}; } constexpr bool foo () { return ((void **) &typeid (int))[0]; } constexpr bool x = foo (); used to be rejected due to the reinterpret_cast in there, but assuming this ICE is fixed, it is rejected with another reason: pr92009.C:9:24: in ‘constexpr’ expansion of ‘foo()’ pr92009.C:9:25: error: the value of ‘_ZTIi’ is not usable in a constant expression 9 | constexpr bool x = foo (); | ^ pr92009.C:6:33: note: ‘_ZTIi’ was not declared ‘constexpr’ 6 | return ((void **) &typeid (int))[0]; | ^ Now, consider struct S { void *p; }; struct T { S s; }; constexpr S s = { nullptr }; constexpr T t = { { nullptr } }; constexpr void * foo () { return ((void **) &t)[0]; } constexpr void * bar () { return ((void **) &s)[0]; } constexpr auto x = foo (); constexpr auto y = bar (); clang++ rejects here both the foo and bar calls as non-constexpr, as reinterpret_cast is encountered. GCC 9 will succeed with cxx_fold_indirect_ref in the bar case and fail the foo case, so rejects foo, but (incorrectly?) accepts bar call. And GCC 10 with the change I've made will accept both. Makes me wonder if cxx_eval_indirect_ref shouldn't evaluate the argument as constant expression no matter if cxx_fold_indirect_ref actually folds it into something or not, so that what is non-constexpr is really diagnosed as such. But am also afraid of what all it will break. Jason, thoughts on this?