aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@gmail.com>2017-05-17 16:54:23 +0300
committerVille Voutilainen <ville@gcc.gnu.org>2017-05-17 16:54:23 +0300
commitb42cc3ca244ea57d5112638a73e7f83c58202a84 (patch)
tree5dba2cc1db7a08d1f9a5a4c2c53436d4d65bed2e /gcc
parent36f4bc9ce82363820ce3aac4bb3f7fbfdeef1663 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c2
-rw-r--r--gcc/c-family/c-common.h1
-rw-r--r--gcc/cp/ChangeLog19
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/cxx-pretty-print.c6
-rw-r--r--gcc/cp/method.c42
-rw-r--r--gcc/cp/parser.c10
-rw-r--r--gcc/cp/semantics.c10
-rw-r--r--gcc/testsuite/g++.dg/ext/80654.C18
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;
+}