Message ID | 20231016001227.2717180-2-kmatsui@gcc.gnu.org |
---|---|
State | New |
Headers | show |
Series | Optimize type traits performance | expand |
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 > > > > > > > > > > > > > > >
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
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(-)