Message ID | 20210422144954.2557181-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: Refine enum direct-list-initialization [CWG2374] | expand |
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 --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" }