[gcc r17-3436] c++/reflection: reject bare [: bases_of(...)[0] :]

Marek Polacek via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:50a2eb56b9a350ecced4db4942e92d463dab8d8f

commit r17-3436-g50a2eb56b9a350ecced4db4942e92d463dab8d8f
Author: Marek Polacek <[email protected]>
Date:   Mon Aug 17 16:37:42 2026 -0400

    c++/reflection: reject bare [: bases_of(...)[0] :]
    
    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.
    
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 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 be3c2c5f86cc..7e962fdc19e5 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 2430b0e136c4..390f249fb0c9 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 fd9fab1efa38..8ef4f7fc0300 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" }
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.