diff mbox series

c++: Refine enum direct-list-initialization [CWG2374]

Message ID 20210422144954.2557181-1-ppalka@redhat.com
State New
Headers show
Series c++: Refine enum direct-list-initialization [CWG2374] | expand

Commit Message

Patrick Palka April 22, 2021, 2:49 p.m. UTC
This implements the wording changes of CWG2374, which clarifies the
wording of P0138 to forbid e.g. direct-list-initialization of a scoped
enumeration from a different scoped enumeration.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

gcc/cp/ChangeLog:

	DR 2374
	* decl.c (is_direct_enum_init): Check the implicit
	convertibility requirement added by CWG 2374.

gcc/testsuite/ChangeLog:

	DR 2374
	* g++.dg/cpp1z/direct-enum-init2.C: New test.
---
 gcc/cp/decl.c                                  | 8 +++++++-
 gcc/testsuite/g++.dg/cpp1z/direct-enum-init2.C | 8 ++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/direct-enum-init2.C

Comments

Jason Merrill April 22, 2021, 10:15 p.m. UTC | #1
On 4/22/21 10:49 AM, Patrick Palka wrote:
> This implements the wording changes of CWG2374, which clarifies the
> wording of P0138 to forbid e.g. direct-list-initialization of a scoped
> enumeration from a different scoped enumeration.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk?

OK.

> gcc/cp/ChangeLog:
> 
> 	DR 2374
> 	* decl.c (is_direct_enum_init): Check the implicit
> 	convertibility requirement added by CWG 2374.
> 
> gcc/testsuite/ChangeLog:
> 
> 	DR 2374
> 	* g++.dg/cpp1z/direct-enum-init2.C: New test.
> ---
>   gcc/cp/decl.c                                  | 8 +++++++-
>   gcc/testsuite/g++.dg/cpp1z/direct-enum-init2.C | 8 ++++++++
>   2 files changed, 15 insertions(+), 1 deletion(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp1z/direct-enum-init2.C
> 
> diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
> index b81de8ef934..60dc2bf182d 100644
> --- a/gcc/cp/decl.c
> +++ b/gcc/cp/decl.c
> @@ -6191,7 +6191,13 @@ is_direct_enum_init (tree type, tree init)
>         && ENUM_FIXED_UNDERLYING_TYPE_P (type)
>         && TREE_CODE (init) == CONSTRUCTOR
>         && CONSTRUCTOR_IS_DIRECT_INIT (init)
> -      && CONSTRUCTOR_NELTS (init) == 1)
> +      && CONSTRUCTOR_NELTS (init) == 1
> +      /* DR 2374: The single element needs to be implicitly
> +	 convertible to the underlying type of the enum.  */
> +      && can_convert_arg (ENUM_UNDERLYING_TYPE (type),
> +			  TREE_TYPE (CONSTRUCTOR_ELT (init, 0)->value),
> +			  CONSTRUCTOR_ELT (init, 0)->value,
> +			  LOOKUP_IMPLICIT, tf_none))
>       return true;
>     return false;
>   }
> diff --git a/gcc/testsuite/g++.dg/cpp1z/direct-enum-init2.C b/gcc/testsuite/g++.dg/cpp1z/direct-enum-init2.C
> new file mode 100644
> index 00000000000..5b94a8d00fe
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp1z/direct-enum-init2.C
> @@ -0,0 +1,8 @@
> +// DR 2374
> +// { dg-do compile { target c++17 } }
> +
> +enum class Orange;
> +enum class Apple;
> +
> +extern Orange o;
> +Apple a{o}; // { dg-error "cannot convert" }
>
diff mbox series

Patch

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b81de8ef934..60dc2bf182d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6191,7 +6191,13 @@  is_direct_enum_init (tree type, tree init)
       && ENUM_FIXED_UNDERLYING_TYPE_P (type)
       && TREE_CODE (init) == CONSTRUCTOR
       && CONSTRUCTOR_IS_DIRECT_INIT (init)
-      && CONSTRUCTOR_NELTS (init) == 1)
+      && CONSTRUCTOR_NELTS (init) == 1
+      /* DR 2374: The single element needs to be implicitly
+	 convertible to the underlying type of the enum.  */
+      && can_convert_arg (ENUM_UNDERLYING_TYPE (type),
+			  TREE_TYPE (CONSTRUCTOR_ELT (init, 0)->value),
+			  CONSTRUCTOR_ELT (init, 0)->value,
+			  LOOKUP_IMPLICIT, tf_none))
     return true;
   return false;
 }
diff --git a/gcc/testsuite/g++.dg/cpp1z/direct-enum-init2.C b/gcc/testsuite/g++.dg/cpp1z/direct-enum-init2.C
new file mode 100644
index 00000000000..5b94a8d00fe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/direct-enum-init2.C
@@ -0,0 +1,8 @@ 
+// DR 2374
+// { dg-do compile { target c++17 } }
+
+enum class Orange;
+enum class Apple;
+
+extern Orange o;
+Apple a{o}; // { dg-error "cannot convert" }