Re: [PATCH] c++/reflection: reject bare [: bases_of(...)[0] :]
Jason Merrill <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
On 8/17/26 4:55 PM, Marek Polacek wrote:
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
OK.
> -- >8 --
> On my P4101 branch splice1.C is crashing in gimplify_expr because we
> fail to reject
>
> [: bases_of (^^T, ctx)[0] :];
>
> which I think should be ill-formed since there's no object. Splicing a NSDM
> also needs an object.
>
> [expr.prim.splice]/2.4 is not explicit about it, but every time the
> standard talks about "designates a direct base class relationship" for
> a splice, it's phrased in terms of E1.E2, like [expr.ref]/6. And
> P3293 also only mentions obj.[: ... :].
>
> gcc/cp/ChangeLog:
>
> * reflect.cc (check_splice_expr): Reject splicing a direct base
> class relationship without an object.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/reflect/mangle3.C: Adjust.
> * g++.dg/reflect/splice1.C: Remove XFAIL.
> ---
> gcc/cp/reflect.cc | 10 ++++++++++
> gcc/testsuite/g++.dg/reflect/mangle3.C | 7 +++++--
> gcc/testsuite/g++.dg/reflect/splice1.C | 2 +-
> 3 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
> index be3c2c5f86c..7e962fdc19e 100644
> --- a/gcc/cp/reflect.cc
> +++ b/gcc/cp/reflect.cc
> @@ -9408,6 +9408,16 @@ check_splice_expr (location_t loc, location_t start_loc, tree t,
> return false;
> }
>
> + /* Like with NSDMs, a bare [:X:] designating a direct base class
> + relationship is ill-formed. */
> + if (!member_access_p && TREE_CODE (t) == TREE_BINFO)
> + {
> + if (complain_p)
> + error_at (loc, "cannot use a base class in a splice expression "
> + "without an object");
> + return false;
> + }
> +
> if (template_p)
> {
> /* [expr.prim.splice] For a splice-expression of the form template
> diff --git a/gcc/testsuite/g++.dg/reflect/mangle3.C b/gcc/testsuite/g++.dg/reflect/mangle3.C
> index 2430b0e136c..390f249fb0c 100644
> --- a/gcc/testsuite/g++.dg/reflect/mangle3.C
> +++ b/gcc/testsuite/g++.dg/reflect/mangle3.C
> @@ -134,6 +134,9 @@ consteval auto f26 (typename [:^^T:] x) { return x; }
> template<info R>
> constexpr auto f27 (typename [:R:]::Alias x) { return x; }
>
> +template<info M>
> +constexpr auto f28 () -> decltype(S{}.[:M:].i) { return 42; }
> +
> void
> g (int p)
> {
> @@ -175,8 +178,6 @@ g (int p)
> // { dg-final { scan-assembler "_Z2f5ILDmvlLi42EEEDtDST_EEv" } }
> f5<std::meta::reflect_object (arr[1])>();
> // { dg-final { scan-assembler "_Z2f5ILDmobixL_Z3arrEL\[ilx]1EEEDtDST_EEv" } }
> - f5<bases_of (^^S, ctx)[0]>();
> -// { dg-final { scan-assembler "_Z2f5ILDmba_1SEEDtDST_EEv" } }
> f6<Y>(Y{42});
> // { dg-final { scan-assembler "_Z2f6I1YEDaDSLDmtyT_EE" } }
> f7<^^TCls>(TCls<0>{});
> @@ -236,4 +237,6 @@ g (int p)
> constexpr auto r = f26<std::meta::info>({});
> f27<^^::>(42);
> // { dg-final { scan-assembler "_Z3f27ILDmgsEEDaNDST_E5AliasE" } }
> + f28<bases_of (^^S, ctx)[0]>();
> +// { dg-final { scan-assembler "_Z3f28ILDmba_1SEEDtdtdttlS0_EDST_E1iEv" } }
> }
> diff --git a/gcc/testsuite/g++.dg/reflect/splice1.C b/gcc/testsuite/g++.dg/reflect/splice1.C
> index fd9fab1efa3..8ef4f7fc030 100644
> --- a/gcc/testsuite/g++.dg/reflect/splice1.C
> +++ b/gcc/testsuite/g++.dg/reflect/splice1.C
> @@ -24,5 +24,5 @@ foo ()
> s.[: (members_of (^^S, ctx) | std::views::filter (is_destructor) | std::ranges::to <std::vector> ())[0] :] (); // { dg-error "cannot use constructor or destructor .constexpr S::~S\\(\\). in a splice expression" }
> [: annotations_of (^^foo)[0] :]; // { dg-error "cannot use an annotation .1. in a splice expression" }
> [: data_member_spec (^^S, { .name = "name" }) :]; // { dg-error "cannot use a data member specification in a splice expression" }
> - [: bases_of (^^T, ctx)[0] :]; // { dg-error "" "" { xfail *-*-* } }
> + [: bases_of (^^T, ctx)[0] :]; // { dg-error "cannot use a base class in a splice expression" }