c++: -Wmissing-field-initializers in unevaluated ctx [PR98620]
authorMarek Polacek <polacek@redhat.com>
Mon, 11 Jan 2021 16:44:36 +0000 (11:44 -0500)
committerMarek Polacek <polacek@redhat.com>
Tue, 12 Jan 2021 03:31:39 +0000 (22:31 -0500)
This PR wants us not to warn about missing field initializers when
the code in question takes places in decltype and similar.  Fixed
thus.

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
gcc/testsuite/g++.dg/warn/Wmissing-field-initializers-2.C [new file with mode: 0644]

index e50d5fe94cd29f2feb4648ac3956572d483e78b7..93744fdafded6526aa24ffe31834003f00b6d39a 100644 (file)
@@ -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 (file)
index 0000000..31d4d89
--- /dev/null
@@ -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;
+}