Message ID | 20210111231911.13798-1-polacek@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: -Wmissing-field-initializers in unevaluated ctx [PR98620] | expand |
On 1/11/21 6:19 PM, Marek Polacek wrote: > This PR wants us not to warn about missing field initializers when > the code in question takes places in decltype and similar. Hmm, the warning seems of questionable utility with templated code like this, but I guess this is a reasonable middle ground. OK. > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > gcc/cp/ChangeLog: > > PR c++/98620 > * typeck2.c (process_init_constructor_record): Don't emit > -Wmissing-field-initializers warnings in unevaluated contexts. > > gcc/testsuite/ChangeLog: > > PR c++/98620 > * g++.dg/warn/Wmissing-field-initializers-2.C: New test. > --- > gcc/cp/typeck2.c | 2 + > .../warn/Wmissing-field-initializers-2.C | 44 +++++++++++++++++++ > 2 files changed, 46 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-2.C > > diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c > index e50d5fe94cd..93744fdafde 100644 > --- a/gcc/cp/typeck2.c > +++ b/gcc/cp/typeck2.c > @@ -1563,6 +1563,7 @@ process_init_constructor_record (tree type, tree init, int nested, int flags, > > /* Warn when some struct elements are implicitly initialized. */ > if ((complain & tf_warning) > + && !cp_unevaluated_operand > && !EMPTY_CONSTRUCTOR_P (init)) > warning (OPT_Wmissing_field_initializers, > "missing initializer for member %qD", field); > @@ -1593,6 +1594,7 @@ process_init_constructor_record (tree type, tree init, int nested, int flags, > /* Warn when some struct elements are implicitly initialized > to zero. */ > if ((complain & tf_warning) > + && !cp_unevaluated_operand > && !EMPTY_CONSTRUCTOR_P (init)) > warning (OPT_Wmissing_field_initializers, > "missing initializer for member %qD", field); > diff --git a/gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-2.C b/gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-2.C > new file mode 100644 > index 00000000000..31d4d897984 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-2.C > @@ -0,0 +1,44 @@ > +// PR c++/98620 > +// { dg-do compile { target c++11 } } > + > +namespace std { > + template<typename T> > + T&& declval() noexcept; > + > + template<bool B> > + struct bool_constant { > + static constexpr bool value = B; > + using type = bool_constant; > + }; > + using true_type = bool_constant<true>; > + using false_type = bool_constant<false>; > +}; > + > +template <typename T> > +struct TmpArray > +{ > + T arr[1]; > +}; > + > +template <typename Src, typename Dst, typename = void> > +struct is_non_narrowing_conversion : std::false_type > +{}; > + > +template <typename Src, typename Dst> > +struct is_non_narrowing_conversion< > + Src, Dst, > + decltype(void(TmpArray<Dst>{{ std::declval<Src>() }})) // { dg-bogus "missing initializer" } > +> : std::true_type > +{}; > + > +struct mystruct > +{ > + int a; > + void * b; > +}; > + > +void test_nok() > +{ > + is_non_narrowing_conversion<int&, mystruct>::type v; > + (void) v; > +} > > base-commit: a958b2fc6dab3d8b01b6ee32178e2fccd97f77f8 >
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index e50d5fe94cd..93744fdafde 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1563,6 +1563,7 @@ process_init_constructor_record (tree type, tree init, int nested, int flags, /* Warn when some struct elements are implicitly initialized. */ if ((complain & tf_warning) + && !cp_unevaluated_operand && !EMPTY_CONSTRUCTOR_P (init)) warning (OPT_Wmissing_field_initializers, "missing initializer for member %qD", field); @@ -1593,6 +1594,7 @@ process_init_constructor_record (tree type, tree init, int nested, int flags, /* Warn when some struct elements are implicitly initialized to zero. */ if ((complain & tf_warning) + && !cp_unevaluated_operand && !EMPTY_CONSTRUCTOR_P (init)) warning (OPT_Wmissing_field_initializers, "missing initializer for member %qD", field); diff --git a/gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-2.C b/gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-2.C new file mode 100644 index 00000000000..31d4d897984 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-2.C @@ -0,0 +1,44 @@ +// PR c++/98620 +// { dg-do compile { target c++11 } } + +namespace std { + template<typename T> + T&& declval() noexcept; + + template<bool B> + struct bool_constant { + static constexpr bool value = B; + using type = bool_constant; + }; + using true_type = bool_constant<true>; + using false_type = bool_constant<false>; +}; + +template <typename T> +struct TmpArray +{ + T arr[1]; +}; + +template <typename Src, typename Dst, typename = void> +struct is_non_narrowing_conversion : std::false_type +{}; + +template <typename Src, typename Dst> +struct is_non_narrowing_conversion< + Src, Dst, + decltype(void(TmpArray<Dst>{{ std::declval<Src>() }})) // { dg-bogus "missing initializer" } +> : std::true_type +{}; + +struct mystruct +{ + int a; + void * b; +}; + +void test_nok() +{ + is_non_narrowing_conversion<int&, mystruct>::type v; + (void) v; +}