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" }
