On Thu, Mar 26, 2026 at 05:56:48PM +0100, Jakub Jelinek wrote:
> Hi!
> 
> This patch attempts to implement this paper.
> Lightly tested so far.
> 
> 2026-03-26  Jakub Jelinek  <[email protected]>
> 
> gcc/cp/
>       * cp-trait.def (__builtin_is_structural): New trait.
>       * semantics.cc (trait_expr_value): Handle CPTK_IS_STRUCTURAL.
>       (finish_trait_expr): Likewise.
>       * constraint.cc (diagnose_trait_expr): Likewise.
>       * metafns.gperf (enum metafn_code): Add METAFN_IS_STRUCTURAL_TYPE.
>       (is_structural_type): New metafn.
>       * metafns.h: Regenerate.
>       * reflect.cc (eval_is_structural_type): New function.
>       (process_metafunction): Handle METAFN_IS_STRUCTURAL_TYPE.
> gcc/testsuite/
>       * g++.dg/reflect/type_trait14.C: New test.
>       * g++.dg/reflect/eh1.C: Add test for is_structural_type.
>       * g++.dg/reflect/eh2.C: Likewise.
> libstdc++-v3/
>       * include/bits/version.def (is_structural): New.
>       * include/bits/version.h: Regenerate.
>       * include/std/type_traits (__glibcxx_want_is_structural): Define.
>       (std::is_structural): New type trait.
>       (std::is_structural_v): New type trait variable template.
>       * include/std/meta (std::meta::is_structural_type): New declaration.
>       * src/c++23/std.cc.in: Export std::is_structural, std::is_structural_v
>       and std::meta::is_structural_type.
>       * 
> testsuite/20_util/is_structural/requirements/explicit_instantiation.cc: New 
> test.
>       * testsuite/20_util/is_structural/requirements/typedefs.cc: New test.
>       * testsuite/20_util/is_structural/value.cc: New test.
>       * testsuite/20_util/variable_templates_for_traits.cc: Test
>       is_structural_v.
> 
> --- gcc/cp/cp-trait.def.jj    2026-01-15 16:33:46.972098555 +0100
> +++ gcc/cp/cp-trait.def       2026-03-26 16:57:51.414942417 +0100
> @@ -98,6 +98,7 @@ DEFTRAIT_EXPR (IS_REFERENCE, "__is_refer
>  DEFTRAIT_EXPR (IS_SAME, "__is_same", 2)
>  DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
>  DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
> +DEFTRAIT_EXPR (IS_STRUCTURAL, "__builtin_is_structural", 1)
>  DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1)
>  DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2)
>  DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", 
> -1)
> --- gcc/cp/semantics.cc.jj    2026-03-12 15:27:17.698072317 +0100
> +++ gcc/cp/semantics.cc       2026-03-26 16:58:37.177163606 +0100
> @@ -14173,6 +14173,9 @@ trait_expr_value (cp_trait_kind kind, tr
>      case CPTK_IS_CONSTEVAL_ONLY:
>        return consteval_only_p (type1);
>  
> +    case CPTK_IS_STRUCTURAL:
> +      return structural_type_p (type1);
> +
>      /* __array_rank, __builtin_type_order and 
> __builtin_structured_binding_size
>         are handled in finish_trait_expr.  */
>      case CPTK_RANK:
> @@ -14354,6 +14357,7 @@ finish_trait_expr (location_t loc, cp_tr
>      case CPTK_IS_TRIVIAL:
>      case CPTK_IS_TRIVIALLY_COPYABLE:
>      case CPTK_IS_CONSTEVAL_ONLY:
> +    case CPTK_IS_STRUCTURAL:
>      case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
>        if (!check_trait_type (type1, /* kind = */ 2))
>       return error_mark_node;
> --- gcc/cp/constraint.cc.jj   2026-03-03 09:43:54.564370259 +0100
> +++ gcc/cp/constraint.cc      2026-03-26 16:58:06.583684262 +0100
> @@ -3357,6 +3357,10 @@ diagnose_trait_expr (location_t loc, tre
>      case CPTK_IS_CONSTEVAL_ONLY:
>        inform (decl_loc, "%qT is not consteval-only", t1);
>        break;
> +    case CPTK_IS_STRUCTURAL:
> +      inform (decl_loc, "%qT is not a structural type", t1);
> +      structural_type_p (t1, /*explain=*/true);
> +      break;
>      case CPTK_RANK:
>        inform (loc, "%qT cannot yield a rank", t1);
>        break;
> --- gcc/cp/metafns.gperf.jj   2026-03-25 20:19:10.715163161 +0100
> +++ gcc/cp/metafns.gperf      2026-03-26 14:31:11.313544554 +0100
> @@ -172,6 +172,7 @@ enum metafn_code {
>    METAFN_IS_FINAL_TYPE,
>    METAFN_IS_AGGREGATE_TYPE,
>    METAFN_IS_CONSTEVAL_ONLY_TYPE,
> +  METAFN_IS_STRUCTURAL_TYPE,
>    METAFN_IS_SIGNED_TYPE,
>    METAFN_IS_UNSIGNED_TYPE,
>    METAFN_IS_BOUNDED_ARRAY_TYPE,
> @@ -607,6 +608,7 @@ is_abstract_type, METAFN_IS_ABSTRACT_TYP
>  is_final_type, METAFN_IS_FINAL_TYPE, METAFN_KIND_BOOL_TINFO,
>  is_aggregate_type, METAFN_IS_AGGREGATE_TYPE, METAFN_KIND_BOOL_TINFO,
>  is_consteval_only_type, METAFN_IS_CONSTEVAL_ONLY_TYPE, 
> METAFN_KIND_BOOL_TINFO,
> +is_structural_type, METAFN_IS_STRUCTURAL_TYPE, METAFN_KIND_BOOL_TINFO,
>  is_signed_type, METAFN_IS_SIGNED_TYPE, METAFN_KIND_BOOL_TINFO,
>  is_unsigned_type, METAFN_IS_UNSIGNED_TYPE, METAFN_KIND_BOOL_TINFO,
>  is_bounded_array_type, METAFN_IS_BOUNDED_ARRAY_TYPE, METAFN_KIND_BOOL_TINFO,
> --- gcc/cp/reflect.cc.jj      2026-03-26 12:30:48.440143055 +0100
> +++ gcc/cp/reflect.cc 2026-03-26 14:33:07.038568698 +0100
> @@ -4362,6 +4362,17 @@ eval_is_consteval_only_type (tree type)
>      return boolean_false_node;
>  }
>  
> +/* Process std::meta::is_structural_type.  */
> +
> +static tree
> +eval_is_structural_type (tree type)
> +{
> +  if (structural_type_p (type))
> +    return boolean_true_node;
> +  else
> +    return boolean_false_node;
> +}

Since this patch is adding the trait, this could be just

  return eval_type_trait (loc, type, CPTK_IS_STRUCTURAL);

Not that it matters in this case...

The cp/ bits look good to me otherwise.

Marek

Reply via email to