[v20,01/40] c++: Sort built-in traits alphabetically
Checks
Commit Message
This patch sorts built-in traits alphabetically for better code
readability.
gcc/cp/ChangeLog:
* constraint.cc (diagnose_trait_expr): Sort built-in traits
alphabetically.
* cp-trait.def: Likewise.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
(finish_trait_type): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/ext/has-builtin-1.C: Sort built-in traits alphabetically.
Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
---
gcc/cp/constraint.cc | 68 ++++++++---------
gcc/cp/cp-trait.def | 10 +--
gcc/cp/semantics.cc | 94 ++++++++++++------------
gcc/testsuite/g++.dg/ext/has-builtin-1.C | 70 +++++++++---------
4 files changed, 121 insertions(+), 121 deletions(-)
Comments
On Sun, 15 Oct 2023, Ken Matsui wrote:
> This patch sorts built-in traits alphabetically for better code
> readability.
Hmm, I'm not sure if we still want/need this change with this current
approach. IIUC gperf would sort the trait names when generating the
hash table code, and so we wanted a more consistent mapping from the
cp-trait.def file to the generated code. But with this current
non-gperf approach I'm inclined to leave the existing ordering alone
for sake of simplicity, and I kind of like that in cp-trait.def we
currently group all expression-yielding traits together and all
type-yielding traits together; that seems like a more natural layout
than plain alphabetical sorting.
>
> gcc/cp/ChangeLog:
>
> * constraint.cc (diagnose_trait_expr): Sort built-in traits
> alphabetically.
> * cp-trait.def: Likewise.
> * semantics.cc (trait_expr_value): Likewise.
> (finish_trait_expr): Likewise.
> (finish_trait_type): Likewise.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/ext/has-builtin-1.C: Sort built-in traits alphabetically.
>
> Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> ---
> gcc/cp/constraint.cc | 68 ++++++++---------
> gcc/cp/cp-trait.def | 10 +--
> gcc/cp/semantics.cc | 94 ++++++++++++------------
> gcc/testsuite/g++.dg/ext/has-builtin-1.C | 70 +++++++++---------
> 4 files changed, 121 insertions(+), 121 deletions(-)
>
> diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
> index c9e4e7043cd..722fc334e6f 100644
> --- a/gcc/cp/constraint.cc
> +++ b/gcc/cp/constraint.cc
> @@ -3702,18 +3702,36 @@ diagnose_trait_expr (tree expr, tree args)
> case CPTK_HAS_TRIVIAL_DESTRUCTOR:
> inform (loc, " %qT is not trivially destructible", t1);
> break;
> + case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> + inform (loc, " %qT does not have unique object representations", t1);
> + break;
> case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> inform (loc, " %qT does not have a virtual destructor", t1);
> break;
> case CPTK_IS_ABSTRACT:
> inform (loc, " %qT is not an abstract class", t1);
> break;
> + case CPTK_IS_AGGREGATE:
> + inform (loc, " %qT is not an aggregate", t1);
> + break;
> + case CPTK_IS_ASSIGNABLE:
> + inform (loc, " %qT is not assignable from %qT", t1, t2);
> + break;
> case CPTK_IS_BASE_OF:
> inform (loc, " %qT is not a base of %qT", t1, t2);
> break;
> case CPTK_IS_CLASS:
> inform (loc, " %qT is not a class", t1);
> break;
> + case CPTK_IS_CONSTRUCTIBLE:
> + if (!t2)
> + inform (loc, " %qT is not default constructible", t1);
> + else
> + inform (loc, " %qT is not constructible from %qE", t1, t2);
> + break;
> + case CPTK_IS_CONVERTIBLE:
> + inform (loc, " %qT is not convertible from %qE", t2, t1);
> + break;
> case CPTK_IS_EMPTY:
> inform (loc, " %qT is not an empty class", t1);
> break;
> @@ -3729,6 +3747,18 @@ diagnose_trait_expr (tree expr, tree args)
> case CPTK_IS_LITERAL_TYPE:
> inform (loc, " %qT is not a literal type", t1);
> break;
> + case CPTK_IS_NOTHROW_ASSIGNABLE:
> + inform (loc, " %qT is not nothrow assignable from %qT", t1, t2);
> + break;
> + case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> + if (!t2)
> + inform (loc, " %qT is not nothrow default constructible", t1);
> + else
> + inform (loc, " %qT is not nothrow constructible from %qE", t1, t2);
> + break;
> + case CPTK_IS_NOTHROW_CONVERTIBLE:
> + inform (loc, " %qT is not nothrow convertible from %qE", t2, t1);
> + break;
> case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
> inform (loc, " %qT is not pointer-interconvertible base of %qT",
> t1, t2);
> @@ -3748,50 +3778,20 @@ diagnose_trait_expr (tree expr, tree args)
> case CPTK_IS_TRIVIAL:
> inform (loc, " %qT is not a trivial type", t1);
> break;
> - case CPTK_IS_UNION:
> - inform (loc, " %qT is not a union", t1);
> - break;
> - case CPTK_IS_AGGREGATE:
> - inform (loc, " %qT is not an aggregate", t1);
> - break;
> - case CPTK_IS_TRIVIALLY_COPYABLE:
> - inform (loc, " %qT is not trivially copyable", t1);
> - break;
> - case CPTK_IS_ASSIGNABLE:
> - inform (loc, " %qT is not assignable from %qT", t1, t2);
> - break;
> case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> inform (loc, " %qT is not trivially assignable from %qT", t1, t2);
> break;
> - case CPTK_IS_NOTHROW_ASSIGNABLE:
> - inform (loc, " %qT is not nothrow assignable from %qT", t1, t2);
> - break;
> - case CPTK_IS_CONSTRUCTIBLE:
> - if (!t2)
> - inform (loc, " %qT is not default constructible", t1);
> - else
> - inform (loc, " %qT is not constructible from %qE", t1, t2);
> - break;
> case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> if (!t2)
> inform (loc, " %qT is not trivially default constructible", t1);
> else
> inform (loc, " %qT is not trivially constructible from %qE", t1, t2);
> break;
> - case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> - if (!t2)
> - inform (loc, " %qT is not nothrow default constructible", t1);
> - else
> - inform (loc, " %qT is not nothrow constructible from %qE", t1, t2);
> - break;
> - case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> - inform (loc, " %qT does not have unique object representations", t1);
> - break;
> - case CPTK_IS_CONVERTIBLE:
> - inform (loc, " %qT is not convertible from %qE", t2, t1);
> + case CPTK_IS_TRIVIALLY_COPYABLE:
> + inform (loc, " %qT is not trivially copyable", t1);
> break;
> - case CPTK_IS_NOTHROW_CONVERTIBLE:
> - inform (loc, " %qT is not nothrow convertible from %qE", t2, t1);
> + case CPTK_IS_UNION:
> + inform (loc, " %qT is not a union", t1);
> break;
> case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> inform (loc, " %qT is not a reference that binds to a temporary "
> diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> index 8b7fece0cc8..0e48e64b8dd 100644
> --- a/gcc/cp/cp-trait.def
> +++ b/gcc/cp/cp-trait.def
> @@ -84,14 +84,14 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
> DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
> DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
> DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
> -/* FIXME Added space to avoid direct usage in GCC 13. */
> -DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
> -
> DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
> -DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
> DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
> -DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
> +DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
> DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
> +DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
> +
> +/* FIXME Added space to avoid direct usage in GCC 13. */
> +DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
>
> /* These traits yield a type pack, not a type, and are represented by
> cp_parser_trait as a special BASES tree instead of a TRAIT_TYPE tree. */
> diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> index 80ef1364e33..782aa515da0 100644
> --- a/gcc/cp/semantics.cc
> +++ b/gcc/cp/semantics.cc
> @@ -12090,15 +12090,6 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> && classtype_has_nothrow_assign_or_copy_p (type1,
> true))));
>
> - case CPTK_HAS_TRIVIAL_ASSIGN:
> - /* ??? The standard seems to be missing the "or array of such a class
> - type" wording for this trait. */
> - type1 = strip_array_types (type1);
> - return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
> - && (trivial_type_p (type1)
> - || (CLASS_TYPE_P (type1)
> - && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
> -
> case CPTK_HAS_NOTHROW_CONSTRUCTOR:
> type1 = strip_array_types (type1);
> return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
> @@ -12107,17 +12098,26 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> && maybe_instantiate_noexcept (t)
> && TYPE_NOTHROW_P (TREE_TYPE (t))));
>
> - case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
> - type1 = strip_array_types (type1);
> - return (trivial_type_p (type1)
> - || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
> -
> case CPTK_HAS_NOTHROW_COPY:
> type1 = strip_array_types (type1);
> return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
> || (CLASS_TYPE_P (type1)
> && classtype_has_nothrow_assign_or_copy_p (type1, false)));
>
> + case CPTK_HAS_TRIVIAL_ASSIGN:
> + /* ??? The standard seems to be missing the "or array of such a class
> + type" wording for this trait. */
> + type1 = strip_array_types (type1);
> + return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
> + && (trivial_type_p (type1)
> + || (CLASS_TYPE_P (type1)
> + && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
> +
> + case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
> + type1 = strip_array_types (type1);
> + return (trivial_type_p (type1)
> + || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
> +
> case CPTK_HAS_TRIVIAL_COPY:
> /* ??? The standard seems to be missing the "or array of such a class
> type" wording for this trait. */
> @@ -12131,18 +12131,21 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> || (CLASS_TYPE_P (type1)
> && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
>
> - case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> - return type_has_virtual_destructor (type1);
> -
> case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> return type_has_unique_obj_representations (type1);
>
> + case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> + return type_has_virtual_destructor (type1);
> +
> case CPTK_IS_ABSTRACT:
> return ABSTRACT_CLASS_TYPE_P (type1);
>
> case CPTK_IS_AGGREGATE:
> return CP_AGGREGATE_TYPE_P (type1);
>
> + case CPTK_IS_ASSIGNABLE:
> + return is_xible (MODIFY_EXPR, type1, type2);
> +
> case CPTK_IS_BASE_OF:
> return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
> && (same_type_ignoring_top_level_qualifiers_p (type1, type2)
> @@ -12151,6 +12154,12 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> case CPTK_IS_CLASS:
> return NON_UNION_CLASS_TYPE_P (type1);
>
> + case CPTK_IS_CONSTRUCTIBLE:
> + return is_xible (INIT_EXPR, type1, type2);
> +
> + case CPTK_IS_CONVERTIBLE:
> + return is_convertible (type1, type2);
> +
> case CPTK_IS_EMPTY:
> return NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1);
>
> @@ -12166,6 +12175,15 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> case CPTK_IS_LITERAL_TYPE:
> return literal_type_p (type1);
>
> + case CPTK_IS_NOTHROW_ASSIGNABLE:
> + return is_nothrow_xible (MODIFY_EXPR, type1, type2);
> +
> + case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> + return is_nothrow_xible (INIT_EXPR, type1, type2);
> +
> + case CPTK_IS_NOTHROW_CONVERTIBLE:
> + return is_nothrow_convertible (type1, type2);
> +
> case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
> return pointer_interconvertible_base_of_p (type1, type2);
>
> @@ -12196,24 +12214,6 @@ 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);
> -
> - case CPTK_IS_NOTHROW_ASSIGNABLE:
> - return is_nothrow_xible (MODIFY_EXPR, type1, type2);
> -
> - case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> - return is_nothrow_xible (INIT_EXPR, type1, type2);
> -
> - case CPTK_IS_CONVERTIBLE:
> - return is_convertible (type1, type2);
> -
> - case CPTK_IS_NOTHROW_CONVERTIBLE:
> - return is_nothrow_convertible (type1, type2);
> -
> case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
>
> @@ -12326,9 +12326,9 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> return error_mark_node;
> break;
>
> + case CPTK_IS_ABSTRACT:
> case CPTK_IS_EMPTY:
> case CPTK_IS_POLYMORPHIC:
> - case CPTK_IS_ABSTRACT:
> case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> if (!check_trait_type (type1, /* kind = */ 3))
> return error_mark_node;
> @@ -12348,12 +12348,12 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> return error_mark_node;
> break;
>
> - case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> - case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> + case CPTK_IS_CONVERTIBLE:
> case CPTK_IS_NOTHROW_ASSIGNABLE:
> case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> - case CPTK_IS_CONVERTIBLE:
> case CPTK_IS_NOTHROW_CONVERTIBLE:
> + case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> + case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> case CPTK_REF_CONVERTS_FROM_TEMPORARY:
> if (!check_trait_type (type1)
> @@ -12372,8 +12372,8 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
>
> case CPTK_IS_CLASS:
> case CPTK_IS_ENUM:
> - case CPTK_IS_UNION:
> case CPTK_IS_SAME:
> + case CPTK_IS_UNION:
> break;
>
> case CPTK_IS_LAYOUT_COMPATIBLE:
> @@ -12436,25 +12436,25 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
>
> switch (kind)
> {
> - case CPTK_UNDERLYING_TYPE:
> - return finish_underlying_type (type1);
> -
> case CPTK_REMOVE_CV:
> return cv_unqualified (type1);
>
> - case CPTK_REMOVE_REFERENCE:
> + case CPTK_REMOVE_CVREF:
> if (TYPE_REF_P (type1))
> type1 = TREE_TYPE (type1);
> - return type1;
> + return cv_unqualified (type1);
>
> - case CPTK_REMOVE_CVREF:
> + case CPTK_REMOVE_REFERENCE:
> if (TYPE_REF_P (type1))
> type1 = TREE_TYPE (type1);
> - return cv_unqualified (type1);
> + return type1;
>
> case CPTK_TYPE_PACK_ELEMENT:
> return finish_type_pack_element (type1, type2, complain);
>
> + case CPTK_UNDERLYING_TYPE:
> + return finish_underlying_type (type1);
> +
> #define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
> case CPTK_##CODE:
> #include "cp-trait.def"
> diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> index f343e153e56..2223f08a628 100644
> --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> @@ -8,9 +8,21 @@
> #if !__has_builtin (__builtin_bit_cast)
> # error "__has_builtin (__builtin_bit_cast) failed"
> #endif
> +#if !__has_builtin (__builtin_is_constant_evaluated)
> +# error "__has_builtin (__builtin_is_constant_evaluated) failed"
> +#endif
> +#if !__has_builtin (__builtin_is_corresponding_member)
> +# error "__has_builtin (__builtin_is_corresponding_member) failed"
> +#endif
> +#if !__has_builtin (__builtin_is_pointer_interconvertible_with_class)
> +# error "__has_builtin (__builtin_is_pointer_interconvertible_with_class) failed"
> +#endif
> #if !__has_builtin (__builtin_launder)
> # error "__has_builtin (__builtin_launder) failed"
> #endif
> +#if !__has_builtin (__builtin_source_location)
> +# error "__has_builtin (__builtin_source_location) failed"
> +#endif
> #if !__has_builtin (__has_nothrow_assign)
> # error "__has_builtin (__has_nothrow_assign) failed"
> #endif
> @@ -44,12 +56,21 @@
> #if !__has_builtin (__is_aggregate)
> # error "__has_builtin (__is_aggregate) failed"
> #endif
> +#if !__has_builtin (__is_assignable)
> +# error "__has_builtin (__is_assignable) failed"
> +#endif
> #if !__has_builtin (__is_base_of)
> # error "__has_builtin (__is_base_of) failed"
> #endif
> #if !__has_builtin (__is_class)
> # error "__has_builtin (__is_class) failed"
> #endif
> +#if !__has_builtin (__is_constructible)
> +# error "__has_builtin (__is_constructible) failed"
> +#endif
> +#if !__has_builtin (__is_convertible)
> +# error "__has_builtin (__is_convertible) failed"
> +#endif
> #if !__has_builtin (__is_empty)
> # error "__has_builtin (__is_empty) failed"
> #endif
> @@ -65,6 +86,15 @@
> #if !__has_builtin (__is_literal_type)
> # error "__has_builtin (__is_literal_type) failed"
> #endif
> +#if !__has_builtin (__is_nothrow_assignable)
> +# error "__has_builtin (__is_nothrow_assignable) failed"
> +#endif
> +#if !__has_builtin (__is_nothrow_constructible)
> +# error "__has_builtin (__is_nothrow_constructible) failed"
> +#endif
> +#if !__has_builtin (__is_nothrow_convertible)
> +# error "__has_builtin (__is_nothrow_convertible) failed"
> +#endif
> #if !__has_builtin (__is_pointer_interconvertible_base_of)
> # error "__has_builtin (__is_pointer_interconvertible_base_of) failed"
> #endif
> @@ -98,51 +128,21 @@
> #if !__has_builtin (__is_union)
> # error "__has_builtin (__is_union) failed"
> #endif
> -#if !__has_builtin (__underlying_type)
> -# error "__has_builtin (__underlying_type) failed"
> -#endif
> -#if !__has_builtin (__is_assignable)
> -# error "__has_builtin (__is_assignable) failed"
> -#endif
> -#if !__has_builtin (__is_constructible)
> -# error "__has_builtin (__is_constructible) failed"
> -#endif
> -#if !__has_builtin (__is_nothrow_assignable)
> -# error "__has_builtin (__is_nothrow_assignable) failed"
> -#endif
> -#if !__has_builtin (__is_nothrow_constructible)
> -# error "__has_builtin (__is_nothrow_constructible) failed"
> -#endif
> #if !__has_builtin (__reference_constructs_from_temporary)
> # error "__has_builtin (__reference_constructs_from_temporary) failed"
> #endif
> #if !__has_builtin (__reference_converts_from_temporary)
> # error "__has_builtin (__reference_converts_from_temporary) failed"
> #endif
> -#if !__has_builtin (__builtin_is_constant_evaluated)
> -# error "__has_builtin (__builtin_is_constant_evaluated) failed"
> -#endif
> -#if !__has_builtin (__builtin_source_location)
> -# error "__has_builtin (__builtin_source_location) failed"
> -#endif
> -#if !__has_builtin (__builtin_is_corresponding_member)
> -# error "__has_builtin (__builtin_is_corresponding_member) failed"
> -#endif
> -#if !__has_builtin (__builtin_is_pointer_interconvertible_with_class)
> -# error "__has_builtin (__builtin_is_pointer_interconvertible_with_class) failed"
> -#endif
> -#if !__has_builtin (__is_convertible)
> -# error "__has_builtin (__is_convertible) failed"
> -#endif
> -#if !__has_builtin (__is_nothrow_convertible)
> -# error "__has_builtin (__is_nothrow_convertible) failed"
> -#endif
> #if !__has_builtin (__remove_cv)
> # error "__has_builtin (__remove_cv) failed"
> #endif
> +#if !__has_builtin (__remove_cvref)
> +# error "__has_builtin (__remove_cvref) failed"
> +#endif
> #if !__has_builtin (__remove_reference)
> # error "__has_builtin (__remove_reference) failed"
> #endif
> -#if !__has_builtin (__remove_cvref)
> -# error "__has_builtin (__remove_cvref) failed"
> +#if !__has_builtin (__underlying_type)
> +# error "__has_builtin (__underlying_type) failed"
> #endif
> --
> 2.42.0
>
>
On Mon, Oct 16, 2023 at 8:17 AM Patrick Palka <ppalka@redhat.com> wrote:
>
> On Sun, 15 Oct 2023, Ken Matsui wrote:
>
> > This patch sorts built-in traits alphabetically for better code
> > readability.
>
> Hmm, I'm not sure if we still want/need this change with this current
> approach. IIUC gperf would sort the trait names when generating the
> hash table code, and so we wanted a more consistent mapping from the
> cp-trait.def file to the generated code. But with this current
> non-gperf approach I'm inclined to leave the existing ordering alone
> for sake of simplicity, and I kind of like that in cp-trait.def we
> currently group all expression-yielding traits together and all
> type-yielding traits together; that seems like a more natural layout
> than plain alphabetical sorting.
>
I see. But this patch is crucial for me to keep all my existing
patches almost conflict-free against rebase, including drop, add, and
edit like you suggested to split integral-related patches. Without
this patch and alphabetical order, I will need to put a new trait in a
random place not close to surrounding commits, as Git relates close
lines when it finds conflicts. When I merged all my patches into one
patch series, I needed to fix conflicts for all my patches almost
every time I rebased. Both thinking of the random place and fixing the
conflicts of all patches would definitely not be desirable. Would you
think we should drop this patch?
> >
> > gcc/cp/ChangeLog:
> >
> > * constraint.cc (diagnose_trait_expr): Sort built-in traits
> > alphabetically.
> > * cp-trait.def: Likewise.
> > * semantics.cc (trait_expr_value): Likewise.
> > (finish_trait_expr): Likewise.
> > (finish_trait_type): Likewise.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * g++.dg/ext/has-builtin-1.C: Sort built-in traits alphabetically.
> >
> > Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> > ---
> > gcc/cp/constraint.cc | 68 ++++++++---------
> > gcc/cp/cp-trait.def | 10 +--
> > gcc/cp/semantics.cc | 94 ++++++++++++------------
> > gcc/testsuite/g++.dg/ext/has-builtin-1.C | 70 +++++++++---------
> > 4 files changed, 121 insertions(+), 121 deletions(-)
> >
> > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
> > index c9e4e7043cd..722fc334e6f 100644
> > --- a/gcc/cp/constraint.cc
> > +++ b/gcc/cp/constraint.cc
> > @@ -3702,18 +3702,36 @@ diagnose_trait_expr (tree expr, tree args)
> > case CPTK_HAS_TRIVIAL_DESTRUCTOR:
> > inform (loc, " %qT is not trivially destructible", t1);
> > break;
> > + case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> > + inform (loc, " %qT does not have unique object representations", t1);
> > + break;
> > case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > inform (loc, " %qT does not have a virtual destructor", t1);
> > break;
> > case CPTK_IS_ABSTRACT:
> > inform (loc, " %qT is not an abstract class", t1);
> > break;
> > + case CPTK_IS_AGGREGATE:
> > + inform (loc, " %qT is not an aggregate", t1);
> > + break;
> > + case CPTK_IS_ASSIGNABLE:
> > + inform (loc, " %qT is not assignable from %qT", t1, t2);
> > + break;
> > case CPTK_IS_BASE_OF:
> > inform (loc, " %qT is not a base of %qT", t1, t2);
> > break;
> > case CPTK_IS_CLASS:
> > inform (loc, " %qT is not a class", t1);
> > break;
> > + case CPTK_IS_CONSTRUCTIBLE:
> > + if (!t2)
> > + inform (loc, " %qT is not default constructible", t1);
> > + else
> > + inform (loc, " %qT is not constructible from %qE", t1, t2);
> > + break;
> > + case CPTK_IS_CONVERTIBLE:
> > + inform (loc, " %qT is not convertible from %qE", t2, t1);
> > + break;
> > case CPTK_IS_EMPTY:
> > inform (loc, " %qT is not an empty class", t1);
> > break;
> > @@ -3729,6 +3747,18 @@ diagnose_trait_expr (tree expr, tree args)
> > case CPTK_IS_LITERAL_TYPE:
> > inform (loc, " %qT is not a literal type", t1);
> > break;
> > + case CPTK_IS_NOTHROW_ASSIGNABLE:
> > + inform (loc, " %qT is not nothrow assignable from %qT", t1, t2);
> > + break;
> > + case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > + if (!t2)
> > + inform (loc, " %qT is not nothrow default constructible", t1);
> > + else
> > + inform (loc, " %qT is not nothrow constructible from %qE", t1, t2);
> > + break;
> > + case CPTK_IS_NOTHROW_CONVERTIBLE:
> > + inform (loc, " %qT is not nothrow convertible from %qE", t2, t1);
> > + break;
> > case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
> > inform (loc, " %qT is not pointer-interconvertible base of %qT",
> > t1, t2);
> > @@ -3748,50 +3778,20 @@ diagnose_trait_expr (tree expr, tree args)
> > case CPTK_IS_TRIVIAL:
> > inform (loc, " %qT is not a trivial type", t1);
> > break;
> > - case CPTK_IS_UNION:
> > - inform (loc, " %qT is not a union", t1);
> > - break;
> > - case CPTK_IS_AGGREGATE:
> > - inform (loc, " %qT is not an aggregate", t1);
> > - break;
> > - case CPTK_IS_TRIVIALLY_COPYABLE:
> > - inform (loc, " %qT is not trivially copyable", t1);
> > - break;
> > - case CPTK_IS_ASSIGNABLE:
> > - inform (loc, " %qT is not assignable from %qT", t1, t2);
> > - break;
> > case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> > inform (loc, " %qT is not trivially assignable from %qT", t1, t2);
> > break;
> > - case CPTK_IS_NOTHROW_ASSIGNABLE:
> > - inform (loc, " %qT is not nothrow assignable from %qT", t1, t2);
> > - break;
> > - case CPTK_IS_CONSTRUCTIBLE:
> > - if (!t2)
> > - inform (loc, " %qT is not default constructible", t1);
> > - else
> > - inform (loc, " %qT is not constructible from %qE", t1, t2);
> > - break;
> > case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> > if (!t2)
> > inform (loc, " %qT is not trivially default constructible", t1);
> > else
> > inform (loc, " %qT is not trivially constructible from %qE", t1, t2);
> > break;
> > - case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > - if (!t2)
> > - inform (loc, " %qT is not nothrow default constructible", t1);
> > - else
> > - inform (loc, " %qT is not nothrow constructible from %qE", t1, t2);
> > - break;
> > - case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> > - inform (loc, " %qT does not have unique object representations", t1);
> > - break;
> > - case CPTK_IS_CONVERTIBLE:
> > - inform (loc, " %qT is not convertible from %qE", t2, t1);
> > + case CPTK_IS_TRIVIALLY_COPYABLE:
> > + inform (loc, " %qT is not trivially copyable", t1);
> > break;
> > - case CPTK_IS_NOTHROW_CONVERTIBLE:
> > - inform (loc, " %qT is not nothrow convertible from %qE", t2, t1);
> > + case CPTK_IS_UNION:
> > + inform (loc, " %qT is not a union", t1);
> > break;
> > case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> > inform (loc, " %qT is not a reference that binds to a temporary "
> > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> > index 8b7fece0cc8..0e48e64b8dd 100644
> > --- a/gcc/cp/cp-trait.def
> > +++ b/gcc/cp/cp-trait.def
> > @@ -84,14 +84,14 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
> > DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
> > DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
> > DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
> > -/* FIXME Added space to avoid direct usage in GCC 13. */
> > -DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
> > -
> > DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
> > -DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
> > DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
> > -DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
> > +DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
> > DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
> > +DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
> > +
> > +/* FIXME Added space to avoid direct usage in GCC 13. */
> > +DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
> >
> > /* These traits yield a type pack, not a type, and are represented by
> > cp_parser_trait as a special BASES tree instead of a TRAIT_TYPE tree. */
> > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> > index 80ef1364e33..782aa515da0 100644
> > --- a/gcc/cp/semantics.cc
> > +++ b/gcc/cp/semantics.cc
> > @@ -12090,15 +12090,6 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > && classtype_has_nothrow_assign_or_copy_p (type1,
> > true))));
> >
> > - case CPTK_HAS_TRIVIAL_ASSIGN:
> > - /* ??? The standard seems to be missing the "or array of such a class
> > - type" wording for this trait. */
> > - type1 = strip_array_types (type1);
> > - return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
> > - && (trivial_type_p (type1)
> > - || (CLASS_TYPE_P (type1)
> > - && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
> > -
> > case CPTK_HAS_NOTHROW_CONSTRUCTOR:
> > type1 = strip_array_types (type1);
> > return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
> > @@ -12107,17 +12098,26 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > && maybe_instantiate_noexcept (t)
> > && TYPE_NOTHROW_P (TREE_TYPE (t))));
> >
> > - case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
> > - type1 = strip_array_types (type1);
> > - return (trivial_type_p (type1)
> > - || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
> > -
> > case CPTK_HAS_NOTHROW_COPY:
> > type1 = strip_array_types (type1);
> > return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
> > || (CLASS_TYPE_P (type1)
> > && classtype_has_nothrow_assign_or_copy_p (type1, false)));
> >
> > + case CPTK_HAS_TRIVIAL_ASSIGN:
> > + /* ??? The standard seems to be missing the "or array of such a class
> > + type" wording for this trait. */
> > + type1 = strip_array_types (type1);
> > + return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
> > + && (trivial_type_p (type1)
> > + || (CLASS_TYPE_P (type1)
> > + && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
> > +
> > + case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
> > + type1 = strip_array_types (type1);
> > + return (trivial_type_p (type1)
> > + || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
> > +
> > case CPTK_HAS_TRIVIAL_COPY:
> > /* ??? The standard seems to be missing the "or array of such a class
> > type" wording for this trait. */
> > @@ -12131,18 +12131,21 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > || (CLASS_TYPE_P (type1)
> > && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
> >
> > - case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > - return type_has_virtual_destructor (type1);
> > -
> > case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> > return type_has_unique_obj_representations (type1);
> >
> > + case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > + return type_has_virtual_destructor (type1);
> > +
> > case CPTK_IS_ABSTRACT:
> > return ABSTRACT_CLASS_TYPE_P (type1);
> >
> > case CPTK_IS_AGGREGATE:
> > return CP_AGGREGATE_TYPE_P (type1);
> >
> > + case CPTK_IS_ASSIGNABLE:
> > + return is_xible (MODIFY_EXPR, type1, type2);
> > +
> > case CPTK_IS_BASE_OF:
> > return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
> > && (same_type_ignoring_top_level_qualifiers_p (type1, type2)
> > @@ -12151,6 +12154,12 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > case CPTK_IS_CLASS:
> > return NON_UNION_CLASS_TYPE_P (type1);
> >
> > + case CPTK_IS_CONSTRUCTIBLE:
> > + return is_xible (INIT_EXPR, type1, type2);
> > +
> > + case CPTK_IS_CONVERTIBLE:
> > + return is_convertible (type1, type2);
> > +
> > case CPTK_IS_EMPTY:
> > return NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1);
> >
> > @@ -12166,6 +12175,15 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > case CPTK_IS_LITERAL_TYPE:
> > return literal_type_p (type1);
> >
> > + case CPTK_IS_NOTHROW_ASSIGNABLE:
> > + return is_nothrow_xible (MODIFY_EXPR, type1, type2);
> > +
> > + case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > + return is_nothrow_xible (INIT_EXPR, type1, type2);
> > +
> > + case CPTK_IS_NOTHROW_CONVERTIBLE:
> > + return is_nothrow_convertible (type1, type2);
> > +
> > case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
> > return pointer_interconvertible_base_of_p (type1, type2);
> >
> > @@ -12196,24 +12214,6 @@ 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);
> > -
> > - case CPTK_IS_NOTHROW_ASSIGNABLE:
> > - return is_nothrow_xible (MODIFY_EXPR, type1, type2);
> > -
> > - case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > - return is_nothrow_xible (INIT_EXPR, type1, type2);
> > -
> > - case CPTK_IS_CONVERTIBLE:
> > - return is_convertible (type1, type2);
> > -
> > - case CPTK_IS_NOTHROW_CONVERTIBLE:
> > - return is_nothrow_convertible (type1, type2);
> > -
> > case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> > return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
> >
> > @@ -12326,9 +12326,9 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> > return error_mark_node;
> > break;
> >
> > + case CPTK_IS_ABSTRACT:
> > case CPTK_IS_EMPTY:
> > case CPTK_IS_POLYMORPHIC:
> > - case CPTK_IS_ABSTRACT:
> > case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > if (!check_trait_type (type1, /* kind = */ 3))
> > return error_mark_node;
> > @@ -12348,12 +12348,12 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> > return error_mark_node;
> > break;
> >
> > - case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> > - case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> > + case CPTK_IS_CONVERTIBLE:
> > case CPTK_IS_NOTHROW_ASSIGNABLE:
> > case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > - case CPTK_IS_CONVERTIBLE:
> > case CPTK_IS_NOTHROW_CONVERTIBLE:
> > + case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> > + case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> > case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> > case CPTK_REF_CONVERTS_FROM_TEMPORARY:
> > if (!check_trait_type (type1)
> > @@ -12372,8 +12372,8 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> >
> > case CPTK_IS_CLASS:
> > case CPTK_IS_ENUM:
> > - case CPTK_IS_UNION:
> > case CPTK_IS_SAME:
> > + case CPTK_IS_UNION:
> > break;
> >
> > case CPTK_IS_LAYOUT_COMPATIBLE:
> > @@ -12436,25 +12436,25 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
> >
> > switch (kind)
> > {
> > - case CPTK_UNDERLYING_TYPE:
> > - return finish_underlying_type (type1);
> > -
> > case CPTK_REMOVE_CV:
> > return cv_unqualified (type1);
> >
> > - case CPTK_REMOVE_REFERENCE:
> > + case CPTK_REMOVE_CVREF:
> > if (TYPE_REF_P (type1))
> > type1 = TREE_TYPE (type1);
> > - return type1;
> > + return cv_unqualified (type1);
> >
> > - case CPTK_REMOVE_CVREF:
> > + case CPTK_REMOVE_REFERENCE:
> > if (TYPE_REF_P (type1))
> > type1 = TREE_TYPE (type1);
> > - return cv_unqualified (type1);
> > + return type1;
> >
> > case CPTK_TYPE_PACK_ELEMENT:
> > return finish_type_pack_element (type1, type2, complain);
> >
> > + case CPTK_UNDERLYING_TYPE:
> > + return finish_underlying_type (type1);
> > +
> > #define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
> > case CPTK_##CODE:
> > #include "cp-trait.def"
> > diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > index f343e153e56..2223f08a628 100644
> > --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > @@ -8,9 +8,21 @@
> > #if !__has_builtin (__builtin_bit_cast)
> > # error "__has_builtin (__builtin_bit_cast) failed"
> > #endif
> > +#if !__has_builtin (__builtin_is_constant_evaluated)
> > +# error "__has_builtin (__builtin_is_constant_evaluated) failed"
> > +#endif
> > +#if !__has_builtin (__builtin_is_corresponding_member)
> > +# error "__has_builtin (__builtin_is_corresponding_member) failed"
> > +#endif
> > +#if !__has_builtin (__builtin_is_pointer_interconvertible_with_class)
> > +# error "__has_builtin (__builtin_is_pointer_interconvertible_with_class) failed"
> > +#endif
> > #if !__has_builtin (__builtin_launder)
> > # error "__has_builtin (__builtin_launder) failed"
> > #endif
> > +#if !__has_builtin (__builtin_source_location)
> > +# error "__has_builtin (__builtin_source_location) failed"
> > +#endif
> > #if !__has_builtin (__has_nothrow_assign)
> > # error "__has_builtin (__has_nothrow_assign) failed"
> > #endif
> > @@ -44,12 +56,21 @@
> > #if !__has_builtin (__is_aggregate)
> > # error "__has_builtin (__is_aggregate) failed"
> > #endif
> > +#if !__has_builtin (__is_assignable)
> > +# error "__has_builtin (__is_assignable) failed"
> > +#endif
> > #if !__has_builtin (__is_base_of)
> > # error "__has_builtin (__is_base_of) failed"
> > #endif
> > #if !__has_builtin (__is_class)
> > # error "__has_builtin (__is_class) failed"
> > #endif
> > +#if !__has_builtin (__is_constructible)
> > +# error "__has_builtin (__is_constructible) failed"
> > +#endif
> > +#if !__has_builtin (__is_convertible)
> > +# error "__has_builtin (__is_convertible) failed"
> > +#endif
> > #if !__has_builtin (__is_empty)
> > # error "__has_builtin (__is_empty) failed"
> > #endif
> > @@ -65,6 +86,15 @@
> > #if !__has_builtin (__is_literal_type)
> > # error "__has_builtin (__is_literal_type) failed"
> > #endif
> > +#if !__has_builtin (__is_nothrow_assignable)
> > +# error "__has_builtin (__is_nothrow_assignable) failed"
> > +#endif
> > +#if !__has_builtin (__is_nothrow_constructible)
> > +# error "__has_builtin (__is_nothrow_constructible) failed"
> > +#endif
> > +#if !__has_builtin (__is_nothrow_convertible)
> > +# error "__has_builtin (__is_nothrow_convertible) failed"
> > +#endif
> > #if !__has_builtin (__is_pointer_interconvertible_base_of)
> > # error "__has_builtin (__is_pointer_interconvertible_base_of) failed"
> > #endif
> > @@ -98,51 +128,21 @@
> > #if !__has_builtin (__is_union)
> > # error "__has_builtin (__is_union) failed"
> > #endif
> > -#if !__has_builtin (__underlying_type)
> > -# error "__has_builtin (__underlying_type) failed"
> > -#endif
> > -#if !__has_builtin (__is_assignable)
> > -# error "__has_builtin (__is_assignable) failed"
> > -#endif
> > -#if !__has_builtin (__is_constructible)
> > -# error "__has_builtin (__is_constructible) failed"
> > -#endif
> > -#if !__has_builtin (__is_nothrow_assignable)
> > -# error "__has_builtin (__is_nothrow_assignable) failed"
> > -#endif
> > -#if !__has_builtin (__is_nothrow_constructible)
> > -# error "__has_builtin (__is_nothrow_constructible) failed"
> > -#endif
> > #if !__has_builtin (__reference_constructs_from_temporary)
> > # error "__has_builtin (__reference_constructs_from_temporary) failed"
> > #endif
> > #if !__has_builtin (__reference_converts_from_temporary)
> > # error "__has_builtin (__reference_converts_from_temporary) failed"
> > #endif
> > -#if !__has_builtin (__builtin_is_constant_evaluated)
> > -# error "__has_builtin (__builtin_is_constant_evaluated) failed"
> > -#endif
> > -#if !__has_builtin (__builtin_source_location)
> > -# error "__has_builtin (__builtin_source_location) failed"
> > -#endif
> > -#if !__has_builtin (__builtin_is_corresponding_member)
> > -# error "__has_builtin (__builtin_is_corresponding_member) failed"
> > -#endif
> > -#if !__has_builtin (__builtin_is_pointer_interconvertible_with_class)
> > -# error "__has_builtin (__builtin_is_pointer_interconvertible_with_class) failed"
> > -#endif
> > -#if !__has_builtin (__is_convertible)
> > -# error "__has_builtin (__is_convertible) failed"
> > -#endif
> > -#if !__has_builtin (__is_nothrow_convertible)
> > -# error "__has_builtin (__is_nothrow_convertible) failed"
> > -#endif
> > #if !__has_builtin (__remove_cv)
> > # error "__has_builtin (__remove_cv) failed"
> > #endif
> > +#if !__has_builtin (__remove_cvref)
> > +# error "__has_builtin (__remove_cvref) failed"
> > +#endif
> > #if !__has_builtin (__remove_reference)
> > # error "__has_builtin (__remove_reference) failed"
> > #endif
> > -#if !__has_builtin (__remove_cvref)
> > -# error "__has_builtin (__remove_cvref) failed"
> > +#if !__has_builtin (__underlying_type)
> > +# error "__has_builtin (__underlying_type) failed"
> > #endif
> > --
> > 2.42.0
> >
> >
>
On Mon, 16 Oct 2023, Ken Matsui wrote:
> On Mon, Oct 16, 2023 at 8:17 AM Patrick Palka <ppalka@redhat.com> wrote:
> >
> > On Sun, 15 Oct 2023, Ken Matsui wrote:
> >
> > > This patch sorts built-in traits alphabetically for better code
> > > readability.
> >
> > Hmm, I'm not sure if we still want/need this change with this current
> > approach. IIUC gperf would sort the trait names when generating the
> > hash table code, and so we wanted a more consistent mapping from the
> > cp-trait.def file to the generated code. But with this current
> > non-gperf approach I'm inclined to leave the existing ordering alone
> > for sake of simplicity, and I kind of like that in cp-trait.def we
> > currently group all expression-yielding traits together and all
> > type-yielding traits together; that seems like a more natural layout
> > than plain alphabetical sorting.
> >
>
> I see. But this patch is crucial for me to keep all my existing
> patches almost conflict-free against rebase, including drop, add, and
> edit like you suggested to split integral-related patches. Without
> this patch and alphabetical order, I will need to put a new trait in a
> random place not close to surrounding commits, as Git relates close
> lines when it finds conflicts. When I merged all my patches into one
> patch series, I needed to fix conflicts for all my patches almost
> every time I rebased. Both thinking of the random place and fixing the
> conflicts of all patches would definitely not be desirable. Would you
> think we should drop this patch?
Fair enough, I'm all for keeping this patch and alphabetizing then :)
>
> > >
> > > gcc/cp/ChangeLog:
> > >
> > > * constraint.cc (diagnose_trait_expr): Sort built-in traits
> > > alphabetically.
> > > * cp-trait.def: Likewise.
> > > * semantics.cc (trait_expr_value): Likewise.
> > > (finish_trait_expr): Likewise.
> > > (finish_trait_type): Likewise.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * g++.dg/ext/has-builtin-1.C: Sort built-in traits alphabetically.
> > >
> > > Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> > > ---
> > > gcc/cp/constraint.cc | 68 ++++++++---------
> > > gcc/cp/cp-trait.def | 10 +--
> > > gcc/cp/semantics.cc | 94 ++++++++++++------------
> > > gcc/testsuite/g++.dg/ext/has-builtin-1.C | 70 +++++++++---------
> > > 4 files changed, 121 insertions(+), 121 deletions(-)
> > >
> > > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
> > > index c9e4e7043cd..722fc334e6f 100644
> > > --- a/gcc/cp/constraint.cc
> > > +++ b/gcc/cp/constraint.cc
> > > @@ -3702,18 +3702,36 @@ diagnose_trait_expr (tree expr, tree args)
> > > case CPTK_HAS_TRIVIAL_DESTRUCTOR:
> > > inform (loc, " %qT is not trivially destructible", t1);
> > > break;
> > > + case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> > > + inform (loc, " %qT does not have unique object representations", t1);
> > > + break;
> > > case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > > inform (loc, " %qT does not have a virtual destructor", t1);
> > > break;
> > > case CPTK_IS_ABSTRACT:
> > > inform (loc, " %qT is not an abstract class", t1);
> > > break;
> > > + case CPTK_IS_AGGREGATE:
> > > + inform (loc, " %qT is not an aggregate", t1);
> > > + break;
> > > + case CPTK_IS_ASSIGNABLE:
> > > + inform (loc, " %qT is not assignable from %qT", t1, t2);
> > > + break;
> > > case CPTK_IS_BASE_OF:
> > > inform (loc, " %qT is not a base of %qT", t1, t2);
> > > break;
> > > case CPTK_IS_CLASS:
> > > inform (loc, " %qT is not a class", t1);
> > > break;
> > > + case CPTK_IS_CONSTRUCTIBLE:
> > > + if (!t2)
> > > + inform (loc, " %qT is not default constructible", t1);
> > > + else
> > > + inform (loc, " %qT is not constructible from %qE", t1, t2);
> > > + break;
> > > + case CPTK_IS_CONVERTIBLE:
> > > + inform (loc, " %qT is not convertible from %qE", t2, t1);
> > > + break;
> > > case CPTK_IS_EMPTY:
> > > inform (loc, " %qT is not an empty class", t1);
> > > break;
> > > @@ -3729,6 +3747,18 @@ diagnose_trait_expr (tree expr, tree args)
> > > case CPTK_IS_LITERAL_TYPE:
> > > inform (loc, " %qT is not a literal type", t1);
> > > break;
> > > + case CPTK_IS_NOTHROW_ASSIGNABLE:
> > > + inform (loc, " %qT is not nothrow assignable from %qT", t1, t2);
> > > + break;
> > > + case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > > + if (!t2)
> > > + inform (loc, " %qT is not nothrow default constructible", t1);
> > > + else
> > > + inform (loc, " %qT is not nothrow constructible from %qE", t1, t2);
> > > + break;
> > > + case CPTK_IS_NOTHROW_CONVERTIBLE:
> > > + inform (loc, " %qT is not nothrow convertible from %qE", t2, t1);
> > > + break;
> > > case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
> > > inform (loc, " %qT is not pointer-interconvertible base of %qT",
> > > t1, t2);
> > > @@ -3748,50 +3778,20 @@ diagnose_trait_expr (tree expr, tree args)
> > > case CPTK_IS_TRIVIAL:
> > > inform (loc, " %qT is not a trivial type", t1);
> > > break;
> > > - case CPTK_IS_UNION:
> > > - inform (loc, " %qT is not a union", t1);
> > > - break;
> > > - case CPTK_IS_AGGREGATE:
> > > - inform (loc, " %qT is not an aggregate", t1);
> > > - break;
> > > - case CPTK_IS_TRIVIALLY_COPYABLE:
> > > - inform (loc, " %qT is not trivially copyable", t1);
> > > - break;
> > > - case CPTK_IS_ASSIGNABLE:
> > > - inform (loc, " %qT is not assignable from %qT", t1, t2);
> > > - break;
> > > case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> > > inform (loc, " %qT is not trivially assignable from %qT", t1, t2);
> > > break;
> > > - case CPTK_IS_NOTHROW_ASSIGNABLE:
> > > - inform (loc, " %qT is not nothrow assignable from %qT", t1, t2);
> > > - break;
> > > - case CPTK_IS_CONSTRUCTIBLE:
> > > - if (!t2)
> > > - inform (loc, " %qT is not default constructible", t1);
> > > - else
> > > - inform (loc, " %qT is not constructible from %qE", t1, t2);
> > > - break;
> > > case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> > > if (!t2)
> > > inform (loc, " %qT is not trivially default constructible", t1);
> > > else
> > > inform (loc, " %qT is not trivially constructible from %qE", t1, t2);
> > > break;
> > > - case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > > - if (!t2)
> > > - inform (loc, " %qT is not nothrow default constructible", t1);
> > > - else
> > > - inform (loc, " %qT is not nothrow constructible from %qE", t1, t2);
> > > - break;
> > > - case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> > > - inform (loc, " %qT does not have unique object representations", t1);
> > > - break;
> > > - case CPTK_IS_CONVERTIBLE:
> > > - inform (loc, " %qT is not convertible from %qE", t2, t1);
> > > + case CPTK_IS_TRIVIALLY_COPYABLE:
> > > + inform (loc, " %qT is not trivially copyable", t1);
> > > break;
> > > - case CPTK_IS_NOTHROW_CONVERTIBLE:
> > > - inform (loc, " %qT is not nothrow convertible from %qE", t2, t1);
> > > + case CPTK_IS_UNION:
> > > + inform (loc, " %qT is not a union", t1);
> > > break;
> > > case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> > > inform (loc, " %qT is not a reference that binds to a temporary "
> > > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> > > index 8b7fece0cc8..0e48e64b8dd 100644
> > > --- a/gcc/cp/cp-trait.def
> > > +++ b/gcc/cp/cp-trait.def
> > > @@ -84,14 +84,14 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
> > > DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
> > > DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
> > > DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
> > > -/* FIXME Added space to avoid direct usage in GCC 13. */
> > > -DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
> > > -
> > > DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
> > > -DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
> > > DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
> > > -DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
> > > +DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
> > > DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
> > > +DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
> > > +
> > > +/* FIXME Added space to avoid direct usage in GCC 13. */
> > > +DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
> > >
> > > /* These traits yield a type pack, not a type, and are represented by
> > > cp_parser_trait as a special BASES tree instead of a TRAIT_TYPE tree. */
> > > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> > > index 80ef1364e33..782aa515da0 100644
> > > --- a/gcc/cp/semantics.cc
> > > +++ b/gcc/cp/semantics.cc
> > > @@ -12090,15 +12090,6 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > > && classtype_has_nothrow_assign_or_copy_p (type1,
> > > true))));
> > >
> > > - case CPTK_HAS_TRIVIAL_ASSIGN:
> > > - /* ??? The standard seems to be missing the "or array of such a class
> > > - type" wording for this trait. */
> > > - type1 = strip_array_types (type1);
> > > - return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
> > > - && (trivial_type_p (type1)
> > > - || (CLASS_TYPE_P (type1)
> > > - && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
> > > -
> > > case CPTK_HAS_NOTHROW_CONSTRUCTOR:
> > > type1 = strip_array_types (type1);
> > > return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
> > > @@ -12107,17 +12098,26 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > > && maybe_instantiate_noexcept (t)
> > > && TYPE_NOTHROW_P (TREE_TYPE (t))));
> > >
> > > - case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
> > > - type1 = strip_array_types (type1);
> > > - return (trivial_type_p (type1)
> > > - || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
> > > -
> > > case CPTK_HAS_NOTHROW_COPY:
> > > type1 = strip_array_types (type1);
> > > return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
> > > || (CLASS_TYPE_P (type1)
> > > && classtype_has_nothrow_assign_or_copy_p (type1, false)));
> > >
> > > + case CPTK_HAS_TRIVIAL_ASSIGN:
> > > + /* ??? The standard seems to be missing the "or array of such a class
> > > + type" wording for this trait. */
> > > + type1 = strip_array_types (type1);
> > > + return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
> > > + && (trivial_type_p (type1)
> > > + || (CLASS_TYPE_P (type1)
> > > + && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
> > > +
> > > + case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
> > > + type1 = strip_array_types (type1);
> > > + return (trivial_type_p (type1)
> > > + || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
> > > +
> > > case CPTK_HAS_TRIVIAL_COPY:
> > > /* ??? The standard seems to be missing the "or array of such a class
> > > type" wording for this trait. */
> > > @@ -12131,18 +12131,21 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > > || (CLASS_TYPE_P (type1)
> > > && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
> > >
> > > - case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > > - return type_has_virtual_destructor (type1);
> > > -
> > > case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> > > return type_has_unique_obj_representations (type1);
> > >
> > > + case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > > + return type_has_virtual_destructor (type1);
> > > +
> > > case CPTK_IS_ABSTRACT:
> > > return ABSTRACT_CLASS_TYPE_P (type1);
> > >
> > > case CPTK_IS_AGGREGATE:
> > > return CP_AGGREGATE_TYPE_P (type1);
> > >
> > > + case CPTK_IS_ASSIGNABLE:
> > > + return is_xible (MODIFY_EXPR, type1, type2);
> > > +
> > > case CPTK_IS_BASE_OF:
> > > return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
> > > && (same_type_ignoring_top_level_qualifiers_p (type1, type2)
> > > @@ -12151,6 +12154,12 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > > case CPTK_IS_CLASS:
> > > return NON_UNION_CLASS_TYPE_P (type1);
> > >
> > > + case CPTK_IS_CONSTRUCTIBLE:
> > > + return is_xible (INIT_EXPR, type1, type2);
> > > +
> > > + case CPTK_IS_CONVERTIBLE:
> > > + return is_convertible (type1, type2);
> > > +
> > > case CPTK_IS_EMPTY:
> > > return NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1);
> > >
> > > @@ -12166,6 +12175,15 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > > case CPTK_IS_LITERAL_TYPE:
> > > return literal_type_p (type1);
> > >
> > > + case CPTK_IS_NOTHROW_ASSIGNABLE:
> > > + return is_nothrow_xible (MODIFY_EXPR, type1, type2);
> > > +
> > > + case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > > + return is_nothrow_xible (INIT_EXPR, type1, type2);
> > > +
> > > + case CPTK_IS_NOTHROW_CONVERTIBLE:
> > > + return is_nothrow_convertible (type1, type2);
> > > +
> > > case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
> > > return pointer_interconvertible_base_of_p (type1, type2);
> > >
> > > @@ -12196,24 +12214,6 @@ 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);
> > > -
> > > - case CPTK_IS_NOTHROW_ASSIGNABLE:
> > > - return is_nothrow_xible (MODIFY_EXPR, type1, type2);
> > > -
> > > - case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > > - return is_nothrow_xible (INIT_EXPR, type1, type2);
> > > -
> > > - case CPTK_IS_CONVERTIBLE:
> > > - return is_convertible (type1, type2);
> > > -
> > > - case CPTK_IS_NOTHROW_CONVERTIBLE:
> > > - return is_nothrow_convertible (type1, type2);
> > > -
> > > case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> > > return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
> > >
> > > @@ -12326,9 +12326,9 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> > > return error_mark_node;
> > > break;
> > >
> > > + case CPTK_IS_ABSTRACT:
> > > case CPTK_IS_EMPTY:
> > > case CPTK_IS_POLYMORPHIC:
> > > - case CPTK_IS_ABSTRACT:
> > > case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > > if (!check_trait_type (type1, /* kind = */ 3))
> > > return error_mark_node;
> > > @@ -12348,12 +12348,12 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> > > return error_mark_node;
> > > break;
> > >
> > > - case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> > > - case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> > > + case CPTK_IS_CONVERTIBLE:
> > > case CPTK_IS_NOTHROW_ASSIGNABLE:
> > > case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > > - case CPTK_IS_CONVERTIBLE:
> > > case CPTK_IS_NOTHROW_CONVERTIBLE:
> > > + case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> > > + case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> > > case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> > > case CPTK_REF_CONVERTS_FROM_TEMPORARY:
> > > if (!check_trait_type (type1)
> > > @@ -12372,8 +12372,8 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> > >
> > > case CPTK_IS_CLASS:
> > > case CPTK_IS_ENUM:
> > > - case CPTK_IS_UNION:
> > > case CPTK_IS_SAME:
> > > + case CPTK_IS_UNION:
> > > break;
> > >
> > > case CPTK_IS_LAYOUT_COMPATIBLE:
> > > @@ -12436,25 +12436,25 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
> > >
> > > switch (kind)
> > > {
> > > - case CPTK_UNDERLYING_TYPE:
> > > - return finish_underlying_type (type1);
> > > -
> > > case CPTK_REMOVE_CV:
> > > return cv_unqualified (type1);
> > >
> > > - case CPTK_REMOVE_REFERENCE:
> > > + case CPTK_REMOVE_CVREF:
> > > if (TYPE_REF_P (type1))
> > > type1 = TREE_TYPE (type1);
> > > - return type1;
> > > + return cv_unqualified (type1);
> > >
> > > - case CPTK_REMOVE_CVREF:
> > > + case CPTK_REMOVE_REFERENCE:
> > > if (TYPE_REF_P (type1))
> > > type1 = TREE_TYPE (type1);
> > > - return cv_unqualified (type1);
> > > + return type1;
> > >
> > > case CPTK_TYPE_PACK_ELEMENT:
> > > return finish_type_pack_element (type1, type2, complain);
> > >
> > > + case CPTK_UNDERLYING_TYPE:
> > > + return finish_underlying_type (type1);
> > > +
> > > #define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
> > > case CPTK_##CODE:
> > > #include "cp-trait.def"
> > > diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > index f343e153e56..2223f08a628 100644
> > > --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > @@ -8,9 +8,21 @@
> > > #if !__has_builtin (__builtin_bit_cast)
> > > # error "__has_builtin (__builtin_bit_cast) failed"
> > > #endif
> > > +#if !__has_builtin (__builtin_is_constant_evaluated)
> > > +# error "__has_builtin (__builtin_is_constant_evaluated) failed"
> > > +#endif
> > > +#if !__has_builtin (__builtin_is_corresponding_member)
> > > +# error "__has_builtin (__builtin_is_corresponding_member) failed"
> > > +#endif
> > > +#if !__has_builtin (__builtin_is_pointer_interconvertible_with_class)
> > > +# error "__has_builtin (__builtin_is_pointer_interconvertible_with_class) failed"
> > > +#endif
> > > #if !__has_builtin (__builtin_launder)
> > > # error "__has_builtin (__builtin_launder) failed"
> > > #endif
> > > +#if !__has_builtin (__builtin_source_location)
> > > +# error "__has_builtin (__builtin_source_location) failed"
> > > +#endif
> > > #if !__has_builtin (__has_nothrow_assign)
> > > # error "__has_builtin (__has_nothrow_assign) failed"
> > > #endif
> > > @@ -44,12 +56,21 @@
> > > #if !__has_builtin (__is_aggregate)
> > > # error "__has_builtin (__is_aggregate) failed"
> > > #endif
> > > +#if !__has_builtin (__is_assignable)
> > > +# error "__has_builtin (__is_assignable) failed"
> > > +#endif
> > > #if !__has_builtin (__is_base_of)
> > > # error "__has_builtin (__is_base_of) failed"
> > > #endif
> > > #if !__has_builtin (__is_class)
> > > # error "__has_builtin (__is_class) failed"
> > > #endif
> > > +#if !__has_builtin (__is_constructible)
> > > +# error "__has_builtin (__is_constructible) failed"
> > > +#endif
> > > +#if !__has_builtin (__is_convertible)
> > > +# error "__has_builtin (__is_convertible) failed"
> > > +#endif
> > > #if !__has_builtin (__is_empty)
> > > # error "__has_builtin (__is_empty) failed"
> > > #endif
> > > @@ -65,6 +86,15 @@
> > > #if !__has_builtin (__is_literal_type)
> > > # error "__has_builtin (__is_literal_type) failed"
> > > #endif
> > > +#if !__has_builtin (__is_nothrow_assignable)
> > > +# error "__has_builtin (__is_nothrow_assignable) failed"
> > > +#endif
> > > +#if !__has_builtin (__is_nothrow_constructible)
> > > +# error "__has_builtin (__is_nothrow_constructible) failed"
> > > +#endif
> > > +#if !__has_builtin (__is_nothrow_convertible)
> > > +# error "__has_builtin (__is_nothrow_convertible) failed"
> > > +#endif
> > > #if !__has_builtin (__is_pointer_interconvertible_base_of)
> > > # error "__has_builtin (__is_pointer_interconvertible_base_of) failed"
> > > #endif
> > > @@ -98,51 +128,21 @@
> > > #if !__has_builtin (__is_union)
> > > # error "__has_builtin (__is_union) failed"
> > > #endif
> > > -#if !__has_builtin (__underlying_type)
> > > -# error "__has_builtin (__underlying_type) failed"
> > > -#endif
> > > -#if !__has_builtin (__is_assignable)
> > > -# error "__has_builtin (__is_assignable) failed"
> > > -#endif
> > > -#if !__has_builtin (__is_constructible)
> > > -# error "__has_builtin (__is_constructible) failed"
> > > -#endif
> > > -#if !__has_builtin (__is_nothrow_assignable)
> > > -# error "__has_builtin (__is_nothrow_assignable) failed"
> > > -#endif
> > > -#if !__has_builtin (__is_nothrow_constructible)
> > > -# error "__has_builtin (__is_nothrow_constructible) failed"
> > > -#endif
> > > #if !__has_builtin (__reference_constructs_from_temporary)
> > > # error "__has_builtin (__reference_constructs_from_temporary) failed"
> > > #endif
> > > #if !__has_builtin (__reference_converts_from_temporary)
> > > # error "__has_builtin (__reference_converts_from_temporary) failed"
> > > #endif
> > > -#if !__has_builtin (__builtin_is_constant_evaluated)
> > > -# error "__has_builtin (__builtin_is_constant_evaluated) failed"
> > > -#endif
> > > -#if !__has_builtin (__builtin_source_location)
> > > -# error "__has_builtin (__builtin_source_location) failed"
> > > -#endif
> > > -#if !__has_builtin (__builtin_is_corresponding_member)
> > > -# error "__has_builtin (__builtin_is_corresponding_member) failed"
> > > -#endif
> > > -#if !__has_builtin (__builtin_is_pointer_interconvertible_with_class)
> > > -# error "__has_builtin (__builtin_is_pointer_interconvertible_with_class) failed"
> > > -#endif
> > > -#if !__has_builtin (__is_convertible)
> > > -# error "__has_builtin (__is_convertible) failed"
> > > -#endif
> > > -#if !__has_builtin (__is_nothrow_convertible)
> > > -# error "__has_builtin (__is_nothrow_convertible) failed"
> > > -#endif
> > > #if !__has_builtin (__remove_cv)
> > > # error "__has_builtin (__remove_cv) failed"
> > > #endif
> > > +#if !__has_builtin (__remove_cvref)
> > > +# error "__has_builtin (__remove_cvref) failed"
> > > +#endif
> > > #if !__has_builtin (__remove_reference)
> > > # error "__has_builtin (__remove_reference) failed"
> > > #endif
> > > -#if !__has_builtin (__remove_cvref)
> > > -# error "__has_builtin (__remove_cvref) failed"
> > > +#if !__has_builtin (__underlying_type)
> > > +# error "__has_builtin (__underlying_type) failed"
> > > #endif
> > > --
> > > 2.42.0
> > >
> > >
> >
>
>
On Mon, Oct 16, 2023 at 2:12 PM Patrick Palka <ppalka@redhat.com> wrote:
>
> On Mon, 16 Oct 2023, Ken Matsui wrote:
>
> > On Mon, Oct 16, 2023 at 8:17 AM Patrick Palka <ppalka@redhat.com> wrote:
> > >
> > > On Sun, 15 Oct 2023, Ken Matsui wrote:
> > >
> > > > This patch sorts built-in traits alphabetically for better code
> > > > readability.
> > >
> > > Hmm, I'm not sure if we still want/need this change with this current
> > > approach. IIUC gperf would sort the trait names when generating the
> > > hash table code, and so we wanted a more consistent mapping from the
> > > cp-trait.def file to the generated code. But with this current
> > > non-gperf approach I'm inclined to leave the existing ordering alone
> > > for sake of simplicity, and I kind of like that in cp-trait.def we
> > > currently group all expression-yielding traits together and all
> > > type-yielding traits together; that seems like a more natural layout
> > > than plain alphabetical sorting.
> > >
> >
> > I see. But this patch is crucial for me to keep all my existing
> > patches almost conflict-free against rebase, including drop, add, and
> > edit like you suggested to split integral-related patches. Without
> > this patch and alphabetical order, I will need to put a new trait in a
> > random place not close to surrounding commits, as Git relates close
> > lines when it finds conflicts. When I merged all my patches into one
> > patch series, I needed to fix conflicts for all my patches almost
> > every time I rebased. Both thinking of the random place and fixing the
> > conflicts of all patches would definitely not be desirable. Would you
> > think we should drop this patch?
>
> Fair enough, I'm all for keeping this patch and alphabetizing then :)
>
Thank you!
> >
> > > >
> > > > gcc/cp/ChangeLog:
> > > >
> > > > * constraint.cc (diagnose_trait_expr): Sort built-in traits
> > > > alphabetically.
> > > > * cp-trait.def: Likewise.
> > > > * semantics.cc (trait_expr_value): Likewise.
> > > > (finish_trait_expr): Likewise.
> > > > (finish_trait_type): Likewise.
> > > >
> > > > gcc/testsuite/ChangeLog:
> > > >
> > > > * g++.dg/ext/has-builtin-1.C: Sort built-in traits alphabetically.
> > > >
> > > > Signed-off-by: Ken Matsui <kmatsui@gcc.gnu.org>
> > > > ---
> > > > gcc/cp/constraint.cc | 68 ++++++++---------
> > > > gcc/cp/cp-trait.def | 10 +--
> > > > gcc/cp/semantics.cc | 94 ++++++++++++------------
> > > > gcc/testsuite/g++.dg/ext/has-builtin-1.C | 70 +++++++++---------
> > > > 4 files changed, 121 insertions(+), 121 deletions(-)
> > > >
> > > > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
> > > > index c9e4e7043cd..722fc334e6f 100644
> > > > --- a/gcc/cp/constraint.cc
> > > > +++ b/gcc/cp/constraint.cc
> > > > @@ -3702,18 +3702,36 @@ diagnose_trait_expr (tree expr, tree args)
> > > > case CPTK_HAS_TRIVIAL_DESTRUCTOR:
> > > > inform (loc, " %qT is not trivially destructible", t1);
> > > > break;
> > > > + case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> > > > + inform (loc, " %qT does not have unique object representations", t1);
> > > > + break;
> > > > case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > > > inform (loc, " %qT does not have a virtual destructor", t1);
> > > > break;
> > > > case CPTK_IS_ABSTRACT:
> > > > inform (loc, " %qT is not an abstract class", t1);
> > > > break;
> > > > + case CPTK_IS_AGGREGATE:
> > > > + inform (loc, " %qT is not an aggregate", t1);
> > > > + break;
> > > > + case CPTK_IS_ASSIGNABLE:
> > > > + inform (loc, " %qT is not assignable from %qT", t1, t2);
> > > > + break;
> > > > case CPTK_IS_BASE_OF:
> > > > inform (loc, " %qT is not a base of %qT", t1, t2);
> > > > break;
> > > > case CPTK_IS_CLASS:
> > > > inform (loc, " %qT is not a class", t1);
> > > > break;
> > > > + case CPTK_IS_CONSTRUCTIBLE:
> > > > + if (!t2)
> > > > + inform (loc, " %qT is not default constructible", t1);
> > > > + else
> > > > + inform (loc, " %qT is not constructible from %qE", t1, t2);
> > > > + break;
> > > > + case CPTK_IS_CONVERTIBLE:
> > > > + inform (loc, " %qT is not convertible from %qE", t2, t1);
> > > > + break;
> > > > case CPTK_IS_EMPTY:
> > > > inform (loc, " %qT is not an empty class", t1);
> > > > break;
> > > > @@ -3729,6 +3747,18 @@ diagnose_trait_expr (tree expr, tree args)
> > > > case CPTK_IS_LITERAL_TYPE:
> > > > inform (loc, " %qT is not a literal type", t1);
> > > > break;
> > > > + case CPTK_IS_NOTHROW_ASSIGNABLE:
> > > > + inform (loc, " %qT is not nothrow assignable from %qT", t1, t2);
> > > > + break;
> > > > + case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > > > + if (!t2)
> > > > + inform (loc, " %qT is not nothrow default constructible", t1);
> > > > + else
> > > > + inform (loc, " %qT is not nothrow constructible from %qE", t1, t2);
> > > > + break;
> > > > + case CPTK_IS_NOTHROW_CONVERTIBLE:
> > > > + inform (loc, " %qT is not nothrow convertible from %qE", t2, t1);
> > > > + break;
> > > > case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
> > > > inform (loc, " %qT is not pointer-interconvertible base of %qT",
> > > > t1, t2);
> > > > @@ -3748,50 +3778,20 @@ diagnose_trait_expr (tree expr, tree args)
> > > > case CPTK_IS_TRIVIAL:
> > > > inform (loc, " %qT is not a trivial type", t1);
> > > > break;
> > > > - case CPTK_IS_UNION:
> > > > - inform (loc, " %qT is not a union", t1);
> > > > - break;
> > > > - case CPTK_IS_AGGREGATE:
> > > > - inform (loc, " %qT is not an aggregate", t1);
> > > > - break;
> > > > - case CPTK_IS_TRIVIALLY_COPYABLE:
> > > > - inform (loc, " %qT is not trivially copyable", t1);
> > > > - break;
> > > > - case CPTK_IS_ASSIGNABLE:
> > > > - inform (loc, " %qT is not assignable from %qT", t1, t2);
> > > > - break;
> > > > case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> > > > inform (loc, " %qT is not trivially assignable from %qT", t1, t2);
> > > > break;
> > > > - case CPTK_IS_NOTHROW_ASSIGNABLE:
> > > > - inform (loc, " %qT is not nothrow assignable from %qT", t1, t2);
> > > > - break;
> > > > - case CPTK_IS_CONSTRUCTIBLE:
> > > > - if (!t2)
> > > > - inform (loc, " %qT is not default constructible", t1);
> > > > - else
> > > > - inform (loc, " %qT is not constructible from %qE", t1, t2);
> > > > - break;
> > > > case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> > > > if (!t2)
> > > > inform (loc, " %qT is not trivially default constructible", t1);
> > > > else
> > > > inform (loc, " %qT is not trivially constructible from %qE", t1, t2);
> > > > break;
> > > > - case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > > > - if (!t2)
> > > > - inform (loc, " %qT is not nothrow default constructible", t1);
> > > > - else
> > > > - inform (loc, " %qT is not nothrow constructible from %qE", t1, t2);
> > > > - break;
> > > > - case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> > > > - inform (loc, " %qT does not have unique object representations", t1);
> > > > - break;
> > > > - case CPTK_IS_CONVERTIBLE:
> > > > - inform (loc, " %qT is not convertible from %qE", t2, t1);
> > > > + case CPTK_IS_TRIVIALLY_COPYABLE:
> > > > + inform (loc, " %qT is not trivially copyable", t1);
> > > > break;
> > > > - case CPTK_IS_NOTHROW_CONVERTIBLE:
> > > > - inform (loc, " %qT is not nothrow convertible from %qE", t2, t1);
> > > > + case CPTK_IS_UNION:
> > > > + inform (loc, " %qT is not a union", t1);
> > > > break;
> > > > case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> > > > inform (loc, " %qT is not a reference that binds to a temporary "
> > > > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
> > > > index 8b7fece0cc8..0e48e64b8dd 100644
> > > > --- a/gcc/cp/cp-trait.def
> > > > +++ b/gcc/cp/cp-trait.def
> > > > @@ -84,14 +84,14 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
> > > > DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
> > > > DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
> > > > DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
> > > > -/* FIXME Added space to avoid direct usage in GCC 13. */
> > > > -DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
> > > > -
> > > > DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
> > > > -DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
> > > > DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
> > > > -DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
> > > > +DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
> > > > DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
> > > > +DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
> > > > +
> > > > +/* FIXME Added space to avoid direct usage in GCC 13. */
> > > > +DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
> > > >
> > > > /* These traits yield a type pack, not a type, and are represented by
> > > > cp_parser_trait as a special BASES tree instead of a TRAIT_TYPE tree. */
> > > > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> > > > index 80ef1364e33..782aa515da0 100644
> > > > --- a/gcc/cp/semantics.cc
> > > > +++ b/gcc/cp/semantics.cc
> > > > @@ -12090,15 +12090,6 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > > > && classtype_has_nothrow_assign_or_copy_p (type1,
> > > > true))));
> > > >
> > > > - case CPTK_HAS_TRIVIAL_ASSIGN:
> > > > - /* ??? The standard seems to be missing the "or array of such a class
> > > > - type" wording for this trait. */
> > > > - type1 = strip_array_types (type1);
> > > > - return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
> > > > - && (trivial_type_p (type1)
> > > > - || (CLASS_TYPE_P (type1)
> > > > - && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
> > > > -
> > > > case CPTK_HAS_NOTHROW_CONSTRUCTOR:
> > > > type1 = strip_array_types (type1);
> > > > return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
> > > > @@ -12107,17 +12098,26 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > > > && maybe_instantiate_noexcept (t)
> > > > && TYPE_NOTHROW_P (TREE_TYPE (t))));
> > > >
> > > > - case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
> > > > - type1 = strip_array_types (type1);
> > > > - return (trivial_type_p (type1)
> > > > - || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
> > > > -
> > > > case CPTK_HAS_NOTHROW_COPY:
> > > > type1 = strip_array_types (type1);
> > > > return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
> > > > || (CLASS_TYPE_P (type1)
> > > > && classtype_has_nothrow_assign_or_copy_p (type1, false)));
> > > >
> > > > + case CPTK_HAS_TRIVIAL_ASSIGN:
> > > > + /* ??? The standard seems to be missing the "or array of such a class
> > > > + type" wording for this trait. */
> > > > + type1 = strip_array_types (type1);
> > > > + return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
> > > > + && (trivial_type_p (type1)
> > > > + || (CLASS_TYPE_P (type1)
> > > > + && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
> > > > +
> > > > + case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
> > > > + type1 = strip_array_types (type1);
> > > > + return (trivial_type_p (type1)
> > > > + || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
> > > > +
> > > > case CPTK_HAS_TRIVIAL_COPY:
> > > > /* ??? The standard seems to be missing the "or array of such a class
> > > > type" wording for this trait. */
> > > > @@ -12131,18 +12131,21 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > > > || (CLASS_TYPE_P (type1)
> > > > && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
> > > >
> > > > - case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > > > - return type_has_virtual_destructor (type1);
> > > > -
> > > > case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
> > > > return type_has_unique_obj_representations (type1);
> > > >
> > > > + case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > > > + return type_has_virtual_destructor (type1);
> > > > +
> > > > case CPTK_IS_ABSTRACT:
> > > > return ABSTRACT_CLASS_TYPE_P (type1);
> > > >
> > > > case CPTK_IS_AGGREGATE:
> > > > return CP_AGGREGATE_TYPE_P (type1);
> > > >
> > > > + case CPTK_IS_ASSIGNABLE:
> > > > + return is_xible (MODIFY_EXPR, type1, type2);
> > > > +
> > > > case CPTK_IS_BASE_OF:
> > > > return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
> > > > && (same_type_ignoring_top_level_qualifiers_p (type1, type2)
> > > > @@ -12151,6 +12154,12 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > > > case CPTK_IS_CLASS:
> > > > return NON_UNION_CLASS_TYPE_P (type1);
> > > >
> > > > + case CPTK_IS_CONSTRUCTIBLE:
> > > > + return is_xible (INIT_EXPR, type1, type2);
> > > > +
> > > > + case CPTK_IS_CONVERTIBLE:
> > > > + return is_convertible (type1, type2);
> > > > +
> > > > case CPTK_IS_EMPTY:
> > > > return NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1);
> > > >
> > > > @@ -12166,6 +12175,15 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
> > > > case CPTK_IS_LITERAL_TYPE:
> > > > return literal_type_p (type1);
> > > >
> > > > + case CPTK_IS_NOTHROW_ASSIGNABLE:
> > > > + return is_nothrow_xible (MODIFY_EXPR, type1, type2);
> > > > +
> > > > + case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > > > + return is_nothrow_xible (INIT_EXPR, type1, type2);
> > > > +
> > > > + case CPTK_IS_NOTHROW_CONVERTIBLE:
> > > > + return is_nothrow_convertible (type1, type2);
> > > > +
> > > > case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
> > > > return pointer_interconvertible_base_of_p (type1, type2);
> > > >
> > > > @@ -12196,24 +12214,6 @@ 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);
> > > > -
> > > > - case CPTK_IS_NOTHROW_ASSIGNABLE:
> > > > - return is_nothrow_xible (MODIFY_EXPR, type1, type2);
> > > > -
> > > > - case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > > > - return is_nothrow_xible (INIT_EXPR, type1, type2);
> > > > -
> > > > - case CPTK_IS_CONVERTIBLE:
> > > > - return is_convertible (type1, type2);
> > > > -
> > > > - case CPTK_IS_NOTHROW_CONVERTIBLE:
> > > > - return is_nothrow_convertible (type1, type2);
> > > > -
> > > > case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> > > > return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
> > > >
> > > > @@ -12326,9 +12326,9 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> > > > return error_mark_node;
> > > > break;
> > > >
> > > > + case CPTK_IS_ABSTRACT:
> > > > case CPTK_IS_EMPTY:
> > > > case CPTK_IS_POLYMORPHIC:
> > > > - case CPTK_IS_ABSTRACT:
> > > > case CPTK_HAS_VIRTUAL_DESTRUCTOR:
> > > > if (!check_trait_type (type1, /* kind = */ 3))
> > > > return error_mark_node;
> > > > @@ -12348,12 +12348,12 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> > > > return error_mark_node;
> > > > break;
> > > >
> > > > - case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> > > > - case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> > > > + case CPTK_IS_CONVERTIBLE:
> > > > case CPTK_IS_NOTHROW_ASSIGNABLE:
> > > > case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
> > > > - case CPTK_IS_CONVERTIBLE:
> > > > case CPTK_IS_NOTHROW_CONVERTIBLE:
> > > > + case CPTK_IS_TRIVIALLY_ASSIGNABLE:
> > > > + case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
> > > > case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
> > > > case CPTK_REF_CONVERTS_FROM_TEMPORARY:
> > > > if (!check_trait_type (type1)
> > > > @@ -12372,8 +12372,8 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
> > > >
> > > > case CPTK_IS_CLASS:
> > > > case CPTK_IS_ENUM:
> > > > - case CPTK_IS_UNION:
> > > > case CPTK_IS_SAME:
> > > > + case CPTK_IS_UNION:
> > > > break;
> > > >
> > > > case CPTK_IS_LAYOUT_COMPATIBLE:
> > > > @@ -12436,25 +12436,25 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
> > > >
> > > > switch (kind)
> > > > {
> > > > - case CPTK_UNDERLYING_TYPE:
> > > > - return finish_underlying_type (type1);
> > > > -
> > > > case CPTK_REMOVE_CV:
> > > > return cv_unqualified (type1);
> > > >
> > > > - case CPTK_REMOVE_REFERENCE:
> > > > + case CPTK_REMOVE_CVREF:
> > > > if (TYPE_REF_P (type1))
> > > > type1 = TREE_TYPE (type1);
> > > > - return type1;
> > > > + return cv_unqualified (type1);
> > > >
> > > > - case CPTK_REMOVE_CVREF:
> > > > + case CPTK_REMOVE_REFERENCE:
> > > > if (TYPE_REF_P (type1))
> > > > type1 = TREE_TYPE (type1);
> > > > - return cv_unqualified (type1);
> > > > + return type1;
> > > >
> > > > case CPTK_TYPE_PACK_ELEMENT:
> > > > return finish_type_pack_element (type1, type2, complain);
> > > >
> > > > + case CPTK_UNDERLYING_TYPE:
> > > > + return finish_underlying_type (type1);
> > > > +
> > > > #define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
> > > > case CPTK_##CODE:
> > > > #include "cp-trait.def"
> > > > diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > > index f343e153e56..2223f08a628 100644
> > > > --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > > +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
> > > > @@ -8,9 +8,21 @@
> > > > #if !__has_builtin (__builtin_bit_cast)
> > > > # error "__has_builtin (__builtin_bit_cast) failed"
> > > > #endif
> > > > +#if !__has_builtin (__builtin_is_constant_evaluated)
> > > > +# error "__has_builtin (__builtin_is_constant_evaluated) failed"
> > > > +#endif
> > > > +#if !__has_builtin (__builtin_is_corresponding_member)
> > > > +# error "__has_builtin (__builtin_is_corresponding_member) failed"
> > > > +#endif
> > > > +#if !__has_builtin (__builtin_is_pointer_interconvertible_with_class)
> > > > +# error "__has_builtin (__builtin_is_pointer_interconvertible_with_class) failed"
> > > > +#endif
> > > > #if !__has_builtin (__builtin_launder)
> > > > # error "__has_builtin (__builtin_launder) failed"
> > > > #endif
> > > > +#if !__has_builtin (__builtin_source_location)
> > > > +# error "__has_builtin (__builtin_source_location) failed"
> > > > +#endif
> > > > #if !__has_builtin (__has_nothrow_assign)
> > > > # error "__has_builtin (__has_nothrow_assign) failed"
> > > > #endif
> > > > @@ -44,12 +56,21 @@
> > > > #if !__has_builtin (__is_aggregate)
> > > > # error "__has_builtin (__is_aggregate) failed"
> > > > #endif
> > > > +#if !__has_builtin (__is_assignable)
> > > > +# error "__has_builtin (__is_assignable) failed"
> > > > +#endif
> > > > #if !__has_builtin (__is_base_of)
> > > > # error "__has_builtin (__is_base_of) failed"
> > > > #endif
> > > > #if !__has_builtin (__is_class)
> > > > # error "__has_builtin (__is_class) failed"
> > > > #endif
> > > > +#if !__has_builtin (__is_constructible)
> > > > +# error "__has_builtin (__is_constructible) failed"
> > > > +#endif
> > > > +#if !__has_builtin (__is_convertible)
> > > > +# error "__has_builtin (__is_convertible) failed"
> > > > +#endif
> > > > #if !__has_builtin (__is_empty)
> > > > # error "__has_builtin (__is_empty) failed"
> > > > #endif
> > > > @@ -65,6 +86,15 @@
> > > > #if !__has_builtin (__is_literal_type)
> > > > # error "__has_builtin (__is_literal_type) failed"
> > > > #endif
> > > > +#if !__has_builtin (__is_nothrow_assignable)
> > > > +# error "__has_builtin (__is_nothrow_assignable) failed"
> > > > +#endif
> > > > +#if !__has_builtin (__is_nothrow_constructible)
> > > > +# error "__has_builtin (__is_nothrow_constructible) failed"
> > > > +#endif
> > > > +#if !__has_builtin (__is_nothrow_convertible)
> > > > +# error "__has_builtin (__is_nothrow_convertible) failed"
> > > > +#endif
> > > > #if !__has_builtin (__is_pointer_interconvertible_base_of)
> > > > # error "__has_builtin (__is_pointer_interconvertible_base_of) failed"
> > > > #endif
> > > > @@ -98,51 +128,21 @@
> > > > #if !__has_builtin (__is_union)
> > > > # error "__has_builtin (__is_union) failed"
> > > > #endif
> > > > -#if !__has_builtin (__underlying_type)
> > > > -# error "__has_builtin (__underlying_type) failed"
> > > > -#endif
> > > > -#if !__has_builtin (__is_assignable)
> > > > -# error "__has_builtin (__is_assignable) failed"
> > > > -#endif
> > > > -#if !__has_builtin (__is_constructible)
> > > > -# error "__has_builtin (__is_constructible) failed"
> > > > -#endif
> > > > -#if !__has_builtin (__is_nothrow_assignable)
> > > > -# error "__has_builtin (__is_nothrow_assignable) failed"
> > > > -#endif
> > > > -#if !__has_builtin (__is_nothrow_constructible)
> > > > -# error "__has_builtin (__is_nothrow_constructible) failed"
> > > > -#endif
> > > > #if !__has_builtin (__reference_constructs_from_temporary)
> > > > # error "__has_builtin (__reference_constructs_from_temporary) failed"
> > > > #endif
> > > > #if !__has_builtin (__reference_converts_from_temporary)
> > > > # error "__has_builtin (__reference_converts_from_temporary) failed"
> > > > #endif
> > > > -#if !__has_builtin (__builtin_is_constant_evaluated)
> > > > -# error "__has_builtin (__builtin_is_constant_evaluated) failed"
> > > > -#endif
> > > > -#if !__has_builtin (__builtin_source_location)
> > > > -# error "__has_builtin (__builtin_source_location) failed"
> > > > -#endif
> > > > -#if !__has_builtin (__builtin_is_corresponding_member)
> > > > -# error "__has_builtin (__builtin_is_corresponding_member) failed"
> > > > -#endif
> > > > -#if !__has_builtin (__builtin_is_pointer_interconvertible_with_class)
> > > > -# error "__has_builtin (__builtin_is_pointer_interconvertible_with_class) failed"
> > > > -#endif
> > > > -#if !__has_builtin (__is_convertible)
> > > > -# error "__has_builtin (__is_convertible) failed"
> > > > -#endif
> > > > -#if !__has_builtin (__is_nothrow_convertible)
> > > > -# error "__has_builtin (__is_nothrow_convertible) failed"
> > > > -#endif
> > > > #if !__has_builtin (__remove_cv)
> > > > # error "__has_builtin (__remove_cv) failed"
> > > > #endif
> > > > +#if !__has_builtin (__remove_cvref)
> > > > +# error "__has_builtin (__remove_cvref) failed"
> > > > +#endif
> > > > #if !__has_builtin (__remove_reference)
> > > > # error "__has_builtin (__remove_reference) failed"
> > > > #endif
> > > > -#if !__has_builtin (__remove_cvref)
> > > > -# error "__has_builtin (__remove_cvref) failed"
> > > > +#if !__has_builtin (__underlying_type)
> > > > +# error "__has_builtin (__underlying_type) failed"
> > > > #endif
> > > > --
> > > > 2.42.0
> > > >
> > > >
> > >
> >
> >
@@ -3702,18 +3702,36 @@ diagnose_trait_expr (tree expr, tree args)
case CPTK_HAS_TRIVIAL_DESTRUCTOR:
inform (loc, " %qT is not trivially destructible", t1);
break;
+ case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
+ inform (loc, " %qT does not have unique object representations", t1);
+ break;
case CPTK_HAS_VIRTUAL_DESTRUCTOR:
inform (loc, " %qT does not have a virtual destructor", t1);
break;
case CPTK_IS_ABSTRACT:
inform (loc, " %qT is not an abstract class", t1);
break;
+ case CPTK_IS_AGGREGATE:
+ inform (loc, " %qT is not an aggregate", t1);
+ break;
+ case CPTK_IS_ASSIGNABLE:
+ inform (loc, " %qT is not assignable from %qT", t1, t2);
+ break;
case CPTK_IS_BASE_OF:
inform (loc, " %qT is not a base of %qT", t1, t2);
break;
case CPTK_IS_CLASS:
inform (loc, " %qT is not a class", t1);
break;
+ case CPTK_IS_CONSTRUCTIBLE:
+ if (!t2)
+ inform (loc, " %qT is not default constructible", t1);
+ else
+ inform (loc, " %qT is not constructible from %qE", t1, t2);
+ break;
+ case CPTK_IS_CONVERTIBLE:
+ inform (loc, " %qT is not convertible from %qE", t2, t1);
+ break;
case CPTK_IS_EMPTY:
inform (loc, " %qT is not an empty class", t1);
break;
@@ -3729,6 +3747,18 @@ diagnose_trait_expr (tree expr, tree args)
case CPTK_IS_LITERAL_TYPE:
inform (loc, " %qT is not a literal type", t1);
break;
+ case CPTK_IS_NOTHROW_ASSIGNABLE:
+ inform (loc, " %qT is not nothrow assignable from %qT", t1, t2);
+ break;
+ case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
+ if (!t2)
+ inform (loc, " %qT is not nothrow default constructible", t1);
+ else
+ inform (loc, " %qT is not nothrow constructible from %qE", t1, t2);
+ break;
+ case CPTK_IS_NOTHROW_CONVERTIBLE:
+ inform (loc, " %qT is not nothrow convertible from %qE", t2, t1);
+ break;
case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
inform (loc, " %qT is not pointer-interconvertible base of %qT",
t1, t2);
@@ -3748,50 +3778,20 @@ diagnose_trait_expr (tree expr, tree args)
case CPTK_IS_TRIVIAL:
inform (loc, " %qT is not a trivial type", t1);
break;
- case CPTK_IS_UNION:
- inform (loc, " %qT is not a union", t1);
- break;
- case CPTK_IS_AGGREGATE:
- inform (loc, " %qT is not an aggregate", t1);
- break;
- case CPTK_IS_TRIVIALLY_COPYABLE:
- inform (loc, " %qT is not trivially copyable", t1);
- break;
- case CPTK_IS_ASSIGNABLE:
- inform (loc, " %qT is not assignable from %qT", t1, t2);
- break;
case CPTK_IS_TRIVIALLY_ASSIGNABLE:
inform (loc, " %qT is not trivially assignable from %qT", t1, t2);
break;
- case CPTK_IS_NOTHROW_ASSIGNABLE:
- inform (loc, " %qT is not nothrow assignable from %qT", t1, t2);
- break;
- case CPTK_IS_CONSTRUCTIBLE:
- if (!t2)
- inform (loc, " %qT is not default constructible", t1);
- else
- inform (loc, " %qT is not constructible from %qE", t1, t2);
- break;
case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
if (!t2)
inform (loc, " %qT is not trivially default constructible", t1);
else
inform (loc, " %qT is not trivially constructible from %qE", t1, t2);
break;
- case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
- if (!t2)
- inform (loc, " %qT is not nothrow default constructible", t1);
- else
- inform (loc, " %qT is not nothrow constructible from %qE", t1, t2);
- break;
- case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
- inform (loc, " %qT does not have unique object representations", t1);
- break;
- case CPTK_IS_CONVERTIBLE:
- inform (loc, " %qT is not convertible from %qE", t2, t1);
+ case CPTK_IS_TRIVIALLY_COPYABLE:
+ inform (loc, " %qT is not trivially copyable", t1);
break;
- case CPTK_IS_NOTHROW_CONVERTIBLE:
- inform (loc, " %qT is not nothrow convertible from %qE", t2, t1);
+ case CPTK_IS_UNION:
+ inform (loc, " %qT is not a union", t1);
break;
case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
inform (loc, " %qT is not a reference that binds to a temporary "
@@ -84,14 +84,14 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1)
DEFTRAIT_EXPR (IS_UNION, "__is_union", 1)
DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2)
DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2)
-/* FIXME Added space to avoid direct usage in GCC 13. */
-DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
-
DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1)
-DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1)
-DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
+DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1)
DEFTRAIT_TYPE (TYPE_PACK_ELEMENT, "__type_pack_element", -1)
+DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1)
+
+/* FIXME Added space to avoid direct usage in GCC 13. */
+DEFTRAIT_EXPR (IS_DEDUCIBLE, "__is_deducible ", 2)
/* These traits yield a type pack, not a type, and are represented by
cp_parser_trait as a special BASES tree instead of a TRAIT_TYPE tree. */
@@ -12090,15 +12090,6 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
&& classtype_has_nothrow_assign_or_copy_p (type1,
true))));
- case CPTK_HAS_TRIVIAL_ASSIGN:
- /* ??? The standard seems to be missing the "or array of such a class
- type" wording for this trait. */
- type1 = strip_array_types (type1);
- return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
- && (trivial_type_p (type1)
- || (CLASS_TYPE_P (type1)
- && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
-
case CPTK_HAS_NOTHROW_CONSTRUCTOR:
type1 = strip_array_types (type1);
return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
@@ -12107,17 +12098,26 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
&& maybe_instantiate_noexcept (t)
&& TYPE_NOTHROW_P (TREE_TYPE (t))));
- case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
- type1 = strip_array_types (type1);
- return (trivial_type_p (type1)
- || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
-
case CPTK_HAS_NOTHROW_COPY:
type1 = strip_array_types (type1);
return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
|| (CLASS_TYPE_P (type1)
&& classtype_has_nothrow_assign_or_copy_p (type1, false)));
+ case CPTK_HAS_TRIVIAL_ASSIGN:
+ /* ??? The standard seems to be missing the "or array of such a class
+ type" wording for this trait. */
+ type1 = strip_array_types (type1);
+ return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
+ && (trivial_type_p (type1)
+ || (CLASS_TYPE_P (type1)
+ && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
+
+ case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
+ type1 = strip_array_types (type1);
+ return (trivial_type_p (type1)
+ || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
+
case CPTK_HAS_TRIVIAL_COPY:
/* ??? The standard seems to be missing the "or array of such a class
type" wording for this trait. */
@@ -12131,18 +12131,21 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
|| (CLASS_TYPE_P (type1)
&& TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
- case CPTK_HAS_VIRTUAL_DESTRUCTOR:
- return type_has_virtual_destructor (type1);
-
case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
return type_has_unique_obj_representations (type1);
+ case CPTK_HAS_VIRTUAL_DESTRUCTOR:
+ return type_has_virtual_destructor (type1);
+
case CPTK_IS_ABSTRACT:
return ABSTRACT_CLASS_TYPE_P (type1);
case CPTK_IS_AGGREGATE:
return CP_AGGREGATE_TYPE_P (type1);
+ case CPTK_IS_ASSIGNABLE:
+ return is_xible (MODIFY_EXPR, type1, type2);
+
case CPTK_IS_BASE_OF:
return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
&& (same_type_ignoring_top_level_qualifiers_p (type1, type2)
@@ -12151,6 +12154,12 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_CLASS:
return NON_UNION_CLASS_TYPE_P (type1);
+ case CPTK_IS_CONSTRUCTIBLE:
+ return is_xible (INIT_EXPR, type1, type2);
+
+ case CPTK_IS_CONVERTIBLE:
+ return is_convertible (type1, type2);
+
case CPTK_IS_EMPTY:
return NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1);
@@ -12166,6 +12175,15 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_LITERAL_TYPE:
return literal_type_p (type1);
+ case CPTK_IS_NOTHROW_ASSIGNABLE:
+ return is_nothrow_xible (MODIFY_EXPR, type1, type2);
+
+ case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
+ return is_nothrow_xible (INIT_EXPR, type1, type2);
+
+ case CPTK_IS_NOTHROW_CONVERTIBLE:
+ return is_nothrow_convertible (type1, type2);
+
case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
return pointer_interconvertible_base_of_p (type1, type2);
@@ -12196,24 +12214,6 @@ 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);
-
- case CPTK_IS_NOTHROW_ASSIGNABLE:
- return is_nothrow_xible (MODIFY_EXPR, type1, type2);
-
- case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
- return is_nothrow_xible (INIT_EXPR, type1, type2);
-
- case CPTK_IS_CONVERTIBLE:
- return is_convertible (type1, type2);
-
- case CPTK_IS_NOTHROW_CONVERTIBLE:
- return is_nothrow_convertible (type1, type2);
-
case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
@@ -12326,9 +12326,9 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
return error_mark_node;
break;
+ case CPTK_IS_ABSTRACT:
case CPTK_IS_EMPTY:
case CPTK_IS_POLYMORPHIC:
- case CPTK_IS_ABSTRACT:
case CPTK_HAS_VIRTUAL_DESTRUCTOR:
if (!check_trait_type (type1, /* kind = */ 3))
return error_mark_node;
@@ -12348,12 +12348,12 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
return error_mark_node;
break;
- case CPTK_IS_TRIVIALLY_ASSIGNABLE:
- case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
+ case CPTK_IS_CONVERTIBLE:
case CPTK_IS_NOTHROW_ASSIGNABLE:
case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
- case CPTK_IS_CONVERTIBLE:
case CPTK_IS_NOTHROW_CONVERTIBLE:
+ case CPTK_IS_TRIVIALLY_ASSIGNABLE:
+ case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
case CPTK_REF_CONVERTS_FROM_TEMPORARY:
if (!check_trait_type (type1)
@@ -12372,8 +12372,8 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_CLASS:
case CPTK_IS_ENUM:
- case CPTK_IS_UNION:
case CPTK_IS_SAME:
+ case CPTK_IS_UNION:
break;
case CPTK_IS_LAYOUT_COMPATIBLE:
@@ -12436,25 +12436,25 @@ finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
switch (kind)
{
- case CPTK_UNDERLYING_TYPE:
- return finish_underlying_type (type1);
-
case CPTK_REMOVE_CV:
return cv_unqualified (type1);
- case CPTK_REMOVE_REFERENCE:
+ case CPTK_REMOVE_CVREF:
if (TYPE_REF_P (type1))
type1 = TREE_TYPE (type1);
- return type1;
+ return cv_unqualified (type1);
- case CPTK_REMOVE_CVREF:
+ case CPTK_REMOVE_REFERENCE:
if (TYPE_REF_P (type1))
type1 = TREE_TYPE (type1);
- return cv_unqualified (type1);
+ return type1;
case CPTK_TYPE_PACK_ELEMENT:
return finish_type_pack_element (type1, type2, complain);
+ case CPTK_UNDERLYING_TYPE:
+ return finish_underlying_type (type1);
+
#define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
case CPTK_##CODE:
#include "cp-trait.def"
@@ -8,9 +8,21 @@
#if !__has_builtin (__builtin_bit_cast)
# error "__has_builtin (__builtin_bit_cast) failed"
#endif
+#if !__has_builtin (__builtin_is_constant_evaluated)
+# error "__has_builtin (__builtin_is_constant_evaluated) failed"
+#endif
+#if !__has_builtin (__builtin_is_corresponding_member)
+# error "__has_builtin (__builtin_is_corresponding_member) failed"
+#endif
+#if !__has_builtin (__builtin_is_pointer_interconvertible_with_class)
+# error "__has_builtin (__builtin_is_pointer_interconvertible_with_class) failed"
+#endif
#if !__has_builtin (__builtin_launder)
# error "__has_builtin (__builtin_launder) failed"
#endif
+#if !__has_builtin (__builtin_source_location)
+# error "__has_builtin (__builtin_source_location) failed"
+#endif
#if !__has_builtin (__has_nothrow_assign)
# error "__has_builtin (__has_nothrow_assign) failed"
#endif
@@ -44,12 +56,21 @@
#if !__has_builtin (__is_aggregate)
# error "__has_builtin (__is_aggregate) failed"
#endif
+#if !__has_builtin (__is_assignable)
+# error "__has_builtin (__is_assignable) failed"
+#endif
#if !__has_builtin (__is_base_of)
# error "__has_builtin (__is_base_of) failed"
#endif
#if !__has_builtin (__is_class)
# error "__has_builtin (__is_class) failed"
#endif
+#if !__has_builtin (__is_constructible)
+# error "__has_builtin (__is_constructible) failed"
+#endif
+#if !__has_builtin (__is_convertible)
+# error "__has_builtin (__is_convertible) failed"
+#endif
#if !__has_builtin (__is_empty)
# error "__has_builtin (__is_empty) failed"
#endif
@@ -65,6 +86,15 @@
#if !__has_builtin (__is_literal_type)
# error "__has_builtin (__is_literal_type) failed"
#endif
+#if !__has_builtin (__is_nothrow_assignable)
+# error "__has_builtin (__is_nothrow_assignable) failed"
+#endif
+#if !__has_builtin (__is_nothrow_constructible)
+# error "__has_builtin (__is_nothrow_constructible) failed"
+#endif
+#if !__has_builtin (__is_nothrow_convertible)
+# error "__has_builtin (__is_nothrow_convertible) failed"
+#endif
#if !__has_builtin (__is_pointer_interconvertible_base_of)
# error "__has_builtin (__is_pointer_interconvertible_base_of) failed"
#endif
@@ -98,51 +128,21 @@
#if !__has_builtin (__is_union)
# error "__has_builtin (__is_union) failed"
#endif
-#if !__has_builtin (__underlying_type)
-# error "__has_builtin (__underlying_type) failed"
-#endif
-#if !__has_builtin (__is_assignable)
-# error "__has_builtin (__is_assignable) failed"
-#endif
-#if !__has_builtin (__is_constructible)
-# error "__has_builtin (__is_constructible) failed"
-#endif
-#if !__has_builtin (__is_nothrow_assignable)
-# error "__has_builtin (__is_nothrow_assignable) failed"
-#endif
-#if !__has_builtin (__is_nothrow_constructible)
-# error "__has_builtin (__is_nothrow_constructible) failed"
-#endif
#if !__has_builtin (__reference_constructs_from_temporary)
# error "__has_builtin (__reference_constructs_from_temporary) failed"
#endif
#if !__has_builtin (__reference_converts_from_temporary)
# error "__has_builtin (__reference_converts_from_temporary) failed"
#endif
-#if !__has_builtin (__builtin_is_constant_evaluated)
-# error "__has_builtin (__builtin_is_constant_evaluated) failed"
-#endif
-#if !__has_builtin (__builtin_source_location)
-# error "__has_builtin (__builtin_source_location) failed"
-#endif
-#if !__has_builtin (__builtin_is_corresponding_member)
-# error "__has_builtin (__builtin_is_corresponding_member) failed"
-#endif
-#if !__has_builtin (__builtin_is_pointer_interconvertible_with_class)
-# error "__has_builtin (__builtin_is_pointer_interconvertible_with_class) failed"
-#endif
-#if !__has_builtin (__is_convertible)
-# error "__has_builtin (__is_convertible) failed"
-#endif
-#if !__has_builtin (__is_nothrow_convertible)
-# error "__has_builtin (__is_nothrow_convertible) failed"
-#endif
#if !__has_builtin (__remove_cv)
# error "__has_builtin (__remove_cv) failed"
#endif
+#if !__has_builtin (__remove_cvref)
+# error "__has_builtin (__remove_cvref) failed"
+#endif
#if !__has_builtin (__remove_reference)
# error "__has_builtin (__remove_reference) failed"
#endif
-#if !__has_builtin (__remove_cvref)
-# error "__has_builtin (__remove_cvref) failed"
+#if !__has_builtin (__underlying_type)
+# error "__has_builtin (__underlying_type) failed"
#endif