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