aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-09-23 19:38:29 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2016-09-23 19:38:29 +0200
commitd664d76d00b19a61afec13425a9421a62e437505 (patch)
tree0dab028d22f5c23310e12547c146e8c3c2412cbb /gcc/cp
parent24cae8cb9adca74ad4038d2bb55380e486aed8c0 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c27
-rw-r--r--gcc/cp/typeck.c11
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);