https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113705
Alex Coplan <acoplan at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW CC| |acoplan at gcc dot gnu.org Last reconfirmed| |2024-02-01 Ever confirmed|0 |1 --- Comment #2 from Alex Coplan <acoplan at gcc dot gnu.org> --- Confirmed. Here is a reduced testcase that ICEs with -O2 on aarch64-linux-gnu: void free(); template <typename storage> struct generic_wide_int : storage { long elt() const; }; int elt_i; template <typename storage> long generic_wide_int<storage>::elt() const { return this->get_val()[elt_i]; } struct wide_int_storage { struct { long val[0]; long valp; } u; unsigned len; int precision; wide_int_storage(const wide_int_storage &); ~wide_int_storage(); const long *get_val() const; unsigned get_len() const; }; wide_int_storage::wide_int_storage(const wide_int_storage &) { if (__builtin_expect(precision, 0)) u.valp = 0; } wide_int_storage::~wide_int_storage() { if (__builtin_expect(precision, 0)) free(); } const long *wide_int_storage::get_val() const { return u.val; } unsigned wide_int_storage::get_len() const { return len; } struct irange { generic_wide_int<wide_int_storage> upper_bound() const; generic_wide_int<wide_int_storage> *m_base; }; generic_wide_int<wide_int_storage> irange::upper_bound() const { return m_base[1]; } void set_irange() { irange r; for (unsigned i;;) { generic_wide_int __trans_tmp_1 = r.upper_bound(); long *__trans_tmp_2; unsigned short *len; *len = __trans_tmp_1.get_len(); for (i = 0; i < *len; ++i) *__trans_tmp_2++ = __trans_tmp_1.elt(); } }