On 3/4/26 2:35 PM, Boris Staletic wrote:
Bootstrapped and tested on tested on x86_64-pc-linux-gnu.
For the patch I did run the entire `make check`.
I don't think the error message is great,
but I'm not sure how to improve it.
I did try `%D` to format the scope as well,
but that fails when the reflected entity has TU scope.
No need, I think; for decls outside the global namespace printing the
spliced decl will print its scope without needing to repeat it. But
let's use %q#D instead of %<%D%>, 'q' to add quotes and # to add
decl-specifiers. And you might add
inform (DECL_SOURCE_LOCATION (decl), "declared here");
after the error.
-- >8 --
We have to allow splicing "regular" variables
(i.e. VAR_P (name) == true), because of static data members.
The rest of the finish_class_member_access_expr() assumes that,
if there's a scope, it is of a class type (i.e. `CLASS_TYPE_P (scope)`).
For that reason, checking that `CLASS_TYPE_P (scope)` holds (and erroring
otherwise), is necessary.
Signed-off-by: Boris Staletic <[email protected]>
PR c++/123726
gcc/cp/ChangeLog:
* typeck.cc: (finish_class_member_access_expr): Check if
the scope of the spliced entity in a member access expression
is of a class type.
gcc/testsuite/ChangeLog:
* g++.dg/reflect/member21.C: New test.
---
gcc/cp/typeck.cc | 10 +++++++++-
gcc/testsuite/g++.dg/reflect/member21.C | 13 +++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/reflect/member21.C
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 79eb3b5ba2..179e4866fb 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -3600,7 +3600,15 @@ finish_class_member_access_expr (cp_expr object, tree
name, bool template_p,
|| TREE_CODE (name) == CONST_DECL
|| TREE_CODE (name) == FUNCTION_DECL
|| DECL_FUNCTION_TEMPLATE_P (OVL_FIRST (name))))
- scope = context_for_name_lookup (OVL_FIRST (name));
+ {
+ scope = context_for_name_lookup (OVL_FIRST (name));
+ if (!CLASS_TYPE_P (scope))
+ {
+ if (complain & tf_error)
+ error ("%<%D%> is not a member of %qT", name, object_type);
+ return error_mark_node;
+ }
+ }
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{
diff --git a/gcc/testsuite/g++.dg/reflect/member21.C
b/gcc/testsuite/g++.dg/reflect/member21.C
new file mode 100644
index 0000000000..2b6222ec1a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/member21.C
@@ -0,0 +1,13 @@
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+struct S {};
+int x;
+void f() {}
+
+int main() {
+ S s;
+ s.[:^^x:]; // { dg-error "not a member of .S." }
+ s.[:^^s:]; // { dg-error "not a member of .S." }
+ s.[:^^f:]; // { dg-error "not a member of .S." }
+}