diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2017-05-17 16:54:23 +0300 |
---|---|---|
committer | Ville Voutilainen <ville@gcc.gnu.org> | 2017-05-17 16:54:23 +0300 |
commit | b42cc3ca244ea57d5112638a73e7f83c58202a84 (patch) | |
tree | 5dba2cc1db7a08d1f9a5a4c2c53436d4d65bed2e /gcc | |
parent | 36f4bc9ce82363820ce3aac4bb3f7fbfdeef1663 (diff) | |
download | gcc-b42cc3ca244ea57d5112638a73e7f83c58202a84.zip gcc-b42cc3ca244ea57d5112638a73e7f83c58202a84.tar.gz gcc-b42cc3ca244ea57d5112638a73e7f83c58202a84.tar.bz2 |
Implement new C++ intrinsics __is_assignable and __is_constructible.
c-family/
Implement new C++ intrinsics __is_assignable and __is_constructible.
* c-common.c (__is_assignable, __is_constructible): New.
* c-common.h (RID_IS_ASSIGNABLE, RID_IS_CONSTRUCTIBLE): Likewise.
cp/
PR c++/80654
PR c++/80682
Implement new C++ intrinsics __is_assignable and __is_constructible.
* cp-tree.h (CPTK_IS_ASSIGNABLE, CPTK_IS_CONSTRUCTIBLE): New.
(is_xible): New.
* cxx-pretty-print.c (pp_cxx_trait_expression): Handle
CPTK_IS_ASSIGNABLE and CPTK_IS_CONSTRUCTIBLE.
* method.c (constructible_expr): Set cp_unevaluated.
(is_xible_helper): New.
(is_trivially_xible): Adjust.
(is_xible): New.
* parser.c (cp_parser_primary_expression): Handle
RID_IS_ASSIGNABLE and RID_IS_CONSTRUCTIBLE.
(cp_parser_trait_expr): Likewise.
* semantics.c (trait_expr_value): Handle
CPTK_IS_ASSIGNABLE and CPTK_IS_CONSTRUCTIBLE.
testsuite/
* g++.dg/ext/80654.C: New.
libstdc++-v3/
Implement new C++ intrinsics __is_assignable and __is_constructible.
* include/std/type_traits (__do_is_static_castable_impl): Remove.
(__is_static_castable_impl, __is_static_castable_safe): Likewise.
(__is_static_castable, __do_is_direct_constructible_impl): Likewise.
(__is_direct_constructible_impl): Likewise.
(__is_direct_constructible_new_safe): Likewise.
(__is_base_to_derived_ref, __is_lvalue_to_rvalue_ref): Likewise.
(__is_direct_constructible_ref_cast): Likewise.
(__is_direct_constructible_new, __is_direct_constructible): Likewise.
(__do_is_nary_constructible_impl): Likewise.
(__is_nary_constructible_impl, __is_nary_constructible): Likewise.
(__is_constructible_impl): Likewise.
(is_constructible): Call the intrinsic.
(__is_assignable_helper): Remove.
(is_assignable): Call the intrinsic.
(is_trivially_constructible): Likewise.
(__is_trivially_copy_constructible_impl): New.
(is_trivially_copy_constructible): Use it.
(__is_trivially_move_constructible_impl): New.
(is_trivially_move_constructible): Use it.
(is_trivially_assignable): Call the intrinsic.
(__is_trivially_copy_assignable_impl): New.
(is_trivially_copy_assignable): Use it.
(__is_trivially_move_assignable_impl): New.
(is_trivially_move_assignable): Use it.
(testsuite/20_util/declval/requirements/1_neg.cc): Adjust.
(testsuite/20_util/is_trivially_copy_assignable/value.cc):
Add test for void.
(testsuite/20_util/is_trivially_copy_constructible/value.cc): Likewise.
(testsuite/20_util/is_trivially_move_assignable/value.cc): Likewise.
(testsuite/20_util/is_trivially_move_constructible/value.cc): Likewise.
(testsuite/20_util/make_signed/requirements/typedefs_neg.cc): Adjust.
(testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc):
Likewise.
From-SVN: r248153
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c-family/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 2 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 1 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/cxx-pretty-print.c | 6 | ||||
-rw-r--r-- | gcc/cp/method.c | 42 | ||||
-rw-r--r-- | gcc/cp/parser.c | 10 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/80654.C | 18 |
10 files changed, 111 insertions, 8 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 4b1c226..428d733 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2017-05-17 Ville Voutilainen <ville.voutilainen@gmail.com> + + Implement new C++ intrinsics __is_assignable and __is_constructible. + * c-common.c (__is_assignable, __is_constructible): New. + * c-common.h (RID_IS_ASSIGNABLE, RID_IS_CONSTRUCTIBLE): Likewise. + 2017-05-17 Martin Liska <mliska@suse.cz> * c-common.h: Introduce dump_flags_t type and diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index f606e94..a3c63d7 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -514,6 +514,8 @@ const struct c_common_resword c_common_reswords[] = { "volatile", RID_VOLATILE, 0 }, { "wchar_t", RID_WCHAR, D_CXXONLY }, { "while", RID_WHILE, 0 }, + { "__is_assignable", RID_IS_ASSIGNABLE, D_CXXONLY }, + { "__is_constructible", RID_IS_CONSTRUCTIBLE, D_CXXONLY }, /* C++ transactional memory. */ { "synchronized", RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM }, diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 5ce3b45..3023b07 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -172,6 +172,7 @@ enum rid RID_IS_TRIVIALLY_ASSIGNABLE, RID_IS_TRIVIALLY_CONSTRUCTIBLE, RID_IS_TRIVIALLY_COPYABLE, RID_IS_UNION, RID_UNDERLYING_TYPE, + RID_IS_ASSIGNABLE, RID_IS_CONSTRUCTIBLE, /* C++11 */ RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT, diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7136b5d..f657194 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,22 @@ +2017-05-17 Ville Voutilainen <ville.voutilainen@gmail.com> + + PR c++/80654 + PR c++/80682 + Implement new C++ intrinsics __is_assignable and __is_constructible. + * cp-tree.h (CPTK_IS_ASSIGNABLE, CPTK_IS_CONSTRUCTIBLE): New. + (is_xible): New. + * cxx-pretty-print.c (pp_cxx_trait_expression): Handle + CPTK_IS_ASSIGNABLE and CPTK_IS_CONSTRUCTIBLE. + * method.c (constructible_expr): Set cp_unevaluated. + (is_xible_helper): New. + (is_trivially_xible): Adjust. + (is_xible): New. + * parser.c (cp_parser_primary_expression): Handle + RID_IS_ASSIGNABLE and RID_IS_CONSTRUCTIBLE. + (cp_parser_trait_expr): Likewise. + * semantics.c (trait_expr_value): Handle + CPTK_IS_ASSIGNABLE and CPTK_IS_CONSTRUCTIBLE. + 2017-05-17 Nathan Sidwell <nathan@acm.org> * cp-tree.h (ovl_iterator::using_p): New predicate. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 942ac61..9211186 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1016,7 +1016,9 @@ enum cp_trait_kind CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, CPTK_IS_TRIVIALLY_COPYABLE, CPTK_IS_UNION, - CPTK_UNDERLYING_TYPE + CPTK_UNDERLYING_TYPE, + CPTK_IS_ASSIGNABLE, + CPTK_IS_CONSTRUCTIBLE }; /* The types that we are processing. */ @@ -6227,6 +6229,7 @@ extern void use_thunk (tree, bool); extern bool trivial_fn_p (tree); extern tree forward_parm (tree); extern bool is_trivially_xible (enum tree_code, tree, tree); +extern bool is_xible (enum tree_code, tree, tree); extern tree get_defaulted_eh_spec (tree); extern tree unevaluated_noexcept_spec (void); extern void after_nsdmi_defaulted_late_checks (tree); diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index e92a72a..b74a56f 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -2634,6 +2634,12 @@ pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t) case CPTK_IS_LITERAL_TYPE: pp_cxx_ws_string (pp, "__is_literal_type"); break; + case CPTK_IS_ASSIGNABLE: + pp_cxx_ws_string (pp, "__is_assignable"); + break; + case CPTK_IS_CONSTRUCTIBLE: + pp_cxx_ws_string (pp, "__is_constructible"); + break; default: gcc_unreachable (); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 9898ff1..756b59d 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1162,6 +1162,7 @@ constructible_expr (tree to, tree from) { tree ctype = to; vec<tree, va_gc> *args = NULL; + cp_unevaluated cp_uneval_guard; if (TREE_CODE (to) != REFERENCE_TYPE) to = cp_build_reference_type (to, /*rval*/false); tree ob = build_stub_object (to); @@ -1198,22 +1199,36 @@ constructible_expr (tree to, tree from) return expr; } -/* Returns true iff TO is trivially assignable (if CODE is MODIFY_EXPR) or +/* Returns a tree iff TO is assignable (if CODE is MODIFY_EXPR) or constructible (otherwise) from FROM, which is a single type for assignment or a list of types for construction. */ -bool -is_trivially_xible (enum tree_code code, tree to, tree from) +static tree +is_xible_helper (enum tree_code code, tree to, tree from, bool trivial) { - if (VOID_TYPE_P (to)) - return false; + if (VOID_TYPE_P (to) || ABSTRACT_CLASS_TYPE_P (to) + || (from && FUNC_OR_METHOD_TYPE_P (from) + && (TYPE_READONLY (from) || FUNCTION_REF_QUALIFIED (from)))) + return error_mark_node; tree expr; if (code == MODIFY_EXPR) expr = assignable_expr (to, from); - else if (from && TREE_CHAIN (from)) - return false; // only 0- and 1-argument ctors can be trivial + else if (trivial && from && TREE_CHAIN (from)) + return error_mark_node; // only 0- and 1-argument ctors can be trivial else expr = constructible_expr (to, from); + return expr; +} + +/* Returns true iff TO is trivially assignable (if CODE is MODIFY_EXPR) or + constructible (otherwise) from FROM, which is a single type for + assignment or a list of types for construction. */ + +bool +is_trivially_xible (enum tree_code code, tree to, tree from) +{ + tree expr; + expr = is_xible_helper (code, to, from, /*trivial*/true); if (expr == error_mark_node) return false; @@ -1221,6 +1236,19 @@ is_trivially_xible (enum tree_code code, tree to, tree from) return !nt; } +/* Returns true iff TO is assignable (if CODE is MODIFY_EXPR) or + constructible (otherwise) from FROM, which is a single type for + assignment or a list of types for construction. */ + +bool +is_xible (enum tree_code code, tree to, tree from) +{ + tree expr = is_xible_helper (code, to, from, /*trivial*/false); + if (expr == error_mark_node) + return false; + return !!expr; +} + /* Subroutine of synthesized_method_walk. Update SPEC_P, TRIVIAL_P and DELETED_P or give an error message MSG with argument ARG. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7ba2075..7a87a5e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -5135,6 +5135,8 @@ cp_parser_primary_expression (cp_parser *parser, case RID_IS_TRIVIALLY_CONSTRUCTIBLE: case RID_IS_TRIVIALLY_COPYABLE: case RID_IS_UNION: + case RID_IS_ASSIGNABLE: + case RID_IS_CONSTRUCTIBLE: return cp_parser_trait_expr (parser, token->keyword); // C++ concepts @@ -9686,6 +9688,14 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword) case RID_DIRECT_BASES: kind = CPTK_DIRECT_BASES; break; + case RID_IS_ASSIGNABLE: + kind = CPTK_IS_ASSIGNABLE; + binary = true; + break; + case RID_IS_CONSTRUCTIBLE: + kind = CPTK_IS_CONSTRUCTIBLE; + variadic = true; + break; default: gcc_unreachable (); } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index d3249fe..fa02b27 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -9211,6 +9211,12 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_UNION: return type_code1 == UNION_TYPE; + case CPTK_IS_ASSIGNABLE: + return is_xible (MODIFY_EXPR, type1, type2); + + case CPTK_IS_CONSTRUCTIBLE: + return is_xible (INIT_EXPR, type1, type2); + default: gcc_unreachable (); return false; @@ -9284,6 +9290,10 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) return error_mark_node; break; + case CPTK_IS_ASSIGNABLE: + case CPTK_IS_CONSTRUCTIBLE: + break; + case CPTK_IS_TRIVIALLY_ASSIGNABLE: case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE: if (!check_trait_type (type1) diff --git a/gcc/testsuite/g++.dg/ext/80654.C b/gcc/testsuite/g++.dg/ext/80654.C new file mode 100644 index 0000000..8679613 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/80654.C @@ -0,0 +1,18 @@ +// { dg-do compile { target c++11 } } + +template <class T> struct wrap +{ + T t; + wrap(const wrap& other) : t(other.t) {} +}; + +struct nocopy { + nocopy (const nocopy&) = delete; +}; + +int main () +{ + static_assert(!__is_trivially_constructible(wrap<nocopy>, + const wrap<nocopy>&), ""); + return 0; +} |