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. -- >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." } +} -- 2.51.1
