Hi, On 3 Jan 2025, at 21:00, Simon Martin wrote:
> We currently accept this code with c++ <= 17 even though it's invalid > since the base is not initialized (we properly reject it with c++ >= > 20) > > === cut here === > struct NoMut1 { int a, b; }; > struct NoMut3 : NoMut1 { > constexpr NoMut3(int a, int b) {} > }; > void mutable_subobjects() { > constexpr NoMut3 nm3(1, 2); > } > === cut here === > > This is a fallout of r0-118700-gc2b3ec18a494e3, that ignores all > fields > with DECL_ARTIFICIAL in cx_check_missing_mem_inits, including those > that > represent base classes, and need to be checked. > > This patch makes sure that we only skip fields that have > DECL_ARTIFICIAL > if they don't have DECL_FIELD_IS_BASE. > > Successfully tested on x86_64-pc-linux-gnu. Friendly ping. Thanks! Simon > > PR c++/118239 > > gcc/cp/ChangeLog: > > * constexpr.cc (cx_check_missing_mem_inits): Don't skip fields > with DECL_FIELD_IS_BASE. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp0x/constexpr-base8.C: New test. > > --- > gcc/cp/constexpr.cc | 8 +++---- > gcc/testsuite/g++.dg/cpp0x/constexpr-base8.C | 24 > ++++++++++++++++++++ > 2 files changed, 28 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-base8.C > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > index c8be5a525ee..e11444438d3 100644 > --- a/gcc/cp/constexpr.cc > +++ b/gcc/cp/constexpr.cc > @@ -839,9 +839,8 @@ cx_check_missing_mem_inits (tree ctype, tree body, > bool complain) > if (i < nelts) > { > index = CONSTRUCTOR_ELT (body, i)->index; > - /* Skip base and vtable inits. */ > - if (TREE_CODE (index) != FIELD_DECL > - || DECL_ARTIFICIAL (index)) > + /* Skip vtable inits. */ > + if (TREE_CODE (index) != FIELD_DECL) > continue; > } > > @@ -852,7 +851,8 @@ cx_check_missing_mem_inits (tree ctype, tree body, > bool complain) > continue; > if (DECL_UNNAMED_BIT_FIELD (field)) > continue; > - if (DECL_ARTIFICIAL (field)) > + /* Artificial fields can be ignored unless they're bases. */ > + if (DECL_ARTIFICIAL (field) && !DECL_FIELD_IS_BASE (field)) > continue; > if (ANON_AGGR_TYPE_P (TREE_TYPE (field))) > { > diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-base8.C > b/gcc/testsuite/g++.dg/cpp0x/constexpr-base8.C > new file mode 100644 > index 00000000000..ecc28693315 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-base8.C > @@ -0,0 +1,24 @@ > +// PR c++/118239 > +// { dg-do "compile" { target c++11 } } > + > +struct NoMut1 { > + int a, b; > +}; > + > +// Reported case. > +struct NoMut2 : NoMut1 { > + constexpr NoMut2(int a, int b) /*: NoMut1()*/ > + {} // { dg-error "must be initialized" "" { target c++17_down } } > +}; > + > +// Variant with explicit initialization of some member. > +struct NoMut3 : NoMut1 { > + constexpr NoMut3(int a, int b) : c(0) /*, NoMut1()*/ > + {} // { dg-error "must be initialized" "" { target c++17_down } } > + int c; > +}; > + > +void mutable_subobjects() { > + constexpr NoMut2 nm2(1, 2); // { dg-error "constant expression" } > + constexpr NoMut3 nm3(1, 2); // { dg-error "constant expression" } > +} > -- > 2.44.0