Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

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

base-commit: 92bcc711fafc026e0cc2f48b7f3ab23657787a8c
-- 
2.55.0

Reply via email to