[PATCH] c++/reflection: reject bare [: bases_of(...)[0] :]
Marek Polacek <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
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