aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/semantics.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/semantics.cc')
-rw-r--r--gcc/cp/semantics.cc48
1 files changed, 36 insertions, 12 deletions
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index b57547c..77fac45 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -13361,6 +13361,18 @@ object_type_p (const_tree type)
&& !VOID_TYPE_P (type));
}
+/* [defns.referenceable] True iff TYPE is a referenceable type. */
+
+static bool
+referenceable_type_p (const_tree type)
+{
+ return (TYPE_REF_P (type)
+ || object_type_p (type)
+ || (FUNC_OR_METHOD_TYPE_P (type)
+ && type_memfn_quals (type) == TYPE_UNQUALIFIED
+ && type_memfn_rqual (type) == REF_QUAL_NONE));
+}
+
/* Actually evaluates the trait. */
static bool
@@ -13530,6 +13542,21 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_NOTHROW_INVOCABLE:
return expr_noexcept_p (build_invoke (type1, type2, tf_none), tf_none);
+ case CPTK_IS_NOTHROW_RELOCATABLE:
+ if (trivially_relocatable_type_p (type1))
+ return true;
+ else
+ {
+ type1 = strip_array_types (type1);
+ if (!referenceable_type_p (type1))
+ return false;
+ tree arg = make_tree_vec (1);
+ TREE_VEC_ELT (arg, 0)
+ = cp_build_reference_type (type1, /*rval=*/true);
+ return (is_nothrow_xible (INIT_EXPR, type1, arg)
+ && is_nothrow_xible (BIT_NOT_EXPR, type1, NULL_TREE));
+ }
+
case CPTK_IS_OBJECT:
return object_type_p (type1);
@@ -13548,6 +13575,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_REFERENCE:
return type_code1 == REFERENCE_TYPE;
+ case CPTK_IS_REPLACEABLE:
+ return replaceable_type_p (type1);
+
case CPTK_IS_SAME:
return same_type_p (type1, type2);
@@ -13572,6 +13602,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
return is_trivially_xible (BIT_NOT_EXPR, type1, NULL_TREE);
+ case CPTK_IS_TRIVIALLY_RELOCATABLE:
+ return trivially_relocatable_type_p (type1);
+
case CPTK_IS_UNBOUNDED_ARRAY:
return array_of_unknown_bound_p (type1);
@@ -13702,18 +13735,6 @@ same_type_ref_bind_p (cp_trait_kind kind, tree type1, tree type2)
(non_reference (to), non_reference (from))));
}
-/* [defns.referenceable] True iff TYPE is a referenceable type. */
-
-static bool
-referenceable_type_p (const_tree type)
-{
- return (TYPE_REF_P (type)
- || object_type_p (type)
- || (FUNC_OR_METHOD_TYPE_P (type)
- && (type_memfn_quals (type) == TYPE_UNQUALIFIED
- && type_memfn_rqual (type) == REF_QUAL_NONE)));
-}
-
/* Process a trait expression. */
tree
@@ -13762,8 +13783,11 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_LITERAL_TYPE:
case CPTK_IS_POD:
case CPTK_IS_STD_LAYOUT:
+ case CPTK_IS_REPLACEABLE:
+ case CPTK_IS_NOTHROW_RELOCATABLE:
case CPTK_IS_TRIVIAL:
case CPTK_IS_TRIVIALLY_COPYABLE:
+ case CPTK_IS_TRIVIALLY_RELOCATABLE:
case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
if (!check_trait_type (type1, /* kind = */ 2))
return error_mark_node;