diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-09-23 19:38:29 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-09-23 19:38:29 +0200 |
commit | d664d76d00b19a61afec13425a9421a62e437505 (patch) | |
tree | 0dab028d22f5c23310e12547c146e8c3c2412cbb /gcc/cp | |
parent | 24cae8cb9adca74ad4038d2bb55380e486aed8c0 (diff) | |
download | gcc-d664d76d00b19a61afec13425a9421a62e437505.zip gcc-d664d76d00b19a61afec13425a9421a62e437505.tar.gz gcc-d664d76d00b19a61afec13425a9421a62e437505.tar.bz2 |
Implement P0138R2, C++17 construction rules for enum class values
Implement P0138R2, C++17 construction rules for enum class values
* cp-tree.h (is_direct_enum_init): Declare.
* decl.c (is_direct_enum_init): New function.
(reshape_init): Use it.
* typeck.c (convert_for_assignment): Likewise.
* g++.dg/cpp1z/direct-enum-init1.C: New test.
From-SVN: r240449
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 27 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 11 |
4 files changed, 45 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7109684..a3430bf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2016-09-23 Jakub Jelinek <jakub@redhat.com> + Implement P0138R2, C++17 construction rules for enum class values + * cp-tree.h (is_direct_enum_init): Declare. + * decl.c (is_direct_enum_init): New function. + (reshape_init): Use it. + * typeck.c (convert_for_assignment): Likewise. + * Make-lang.in (check-c++1z): Pass RUNTESTFLAGS down to make check-g++. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f403340..c7a38fa 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5829,6 +5829,7 @@ extern tree check_elaborated_type_specifier (enum tag_types, tree, bool); extern void warn_extern_redeclared_static (tree, tree); extern tree cxx_comdat_group (tree); extern bool cp_missing_noreturn_ok_p (tree); +extern bool is_direct_enum_init (tree, tree); extern void initialize_artificial_var (tree, vec<constructor_elt, va_gc> *); extern tree check_var_type (tree, tree); extern tree reshape_init (tree, tree, tsubst_flags_t); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 24f71ce..3dfa042 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5581,6 +5581,22 @@ next_initializable_field (tree field) return field; } +/* Return true for [dcl.init.list] direct-list-initialization from + single element of enumeration with a fixed underlying type. */ + +bool +is_direct_enum_init (tree type, tree init) +{ + if (cxx_dialect >= cxx1z + && TREE_CODE (type) == ENUMERAL_TYPE + && ENUM_FIXED_UNDERLYING_TYPE_P (type) + && TREE_CODE (init) == CONSTRUCTOR + && CONSTRUCTOR_IS_DIRECT_INIT (init) + && CONSTRUCTOR_NELTS (init) == 1) + return true; + return false; +} + /* Subroutine of reshape_init_array and reshape_init_vector, which does the actual work. ELT_TYPE is the element type of the array. MAX_INDEX is an INTEGER_CST representing the size of the array minus one (the maximum index), @@ -6026,6 +6042,17 @@ reshape_init (tree type, tree init, tsubst_flags_t complain) if (vec_safe_is_empty (v)) return init; + /* Handle [dcl.init.list] direct-list-initialization from + single element of enumeration with a fixed underlying type. */ + if (is_direct_enum_init (type, init)) + { + tree elt = CONSTRUCTOR_ELT (init, 0)->value; + if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain)) + return cp_build_c_cast (type, elt, tf_warning_or_error); + else + return error_mark_node; + } + /* Recurse on this CONSTRUCTOR. */ d.cur = &(*v)[0]; d.end = d.cur + v->length (); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c53a85a..b2af615 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -8266,6 +8266,17 @@ convert_for_assignment (tree type, tree rhs, if (TREE_CODE (rhs) == NON_LVALUE_EXPR) rhs = TREE_OPERAND (rhs, 0); + /* Handle [dcl.init.list] direct-list-initialization from + single element of enumeration with a fixed underlying type. */ + if (is_direct_enum_init (type, rhs)) + { + tree elt = CONSTRUCTOR_ELT (rhs, 0)->value; + if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain)) + rhs = cp_build_c_cast (type, elt, complain); + else + rhs = error_mark_node; + } + rhstype = TREE_TYPE (rhs); coder = TREE_CODE (rhstype); |