diff mbox series

c++: -Wmissing-field-initializers in unevaluated ctx [PR98620]

Message ID 20210111231911.13798-1-polacek@redhat.com
State New
Headers show
Series c++: -Wmissing-field-initializers in unevaluated ctx [PR98620] | expand

Commit Message

Marek Polacek Jan. 11, 2021, 11:19 p.m. UTC
This PR wants us not to warn about missing field initializers when
the code in question takes places in decltype and similar.  Fixed
thus.

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


base-commit: a958b2fc6dab3d8b01b6ee32178e2fccd97f77f8

Comments

Jason Merrill Jan. 12, 2021, 2:08 a.m. UTC | #1
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 mbox series

Patch

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;
+}