https://gcc.gnu.org/g:f3bf6e14360d7a6d5ecca494b94a2165a97ec34c
commit r16-7043-gf3bf6e14360d7a6d5ecca494b94a2165a97ec34c Author: Marek Polacek <[email protected]> Date: Thu Jan 22 15:52:45 2026 -0500 c++/reflection: detect more invalid splices in lambda The comment for check_splice_expr in <https://gcc.gnu.org/pipermail/gcc-patches/2025-December/704168.html> points out that I wasn't giving an error for this testcase. (clang++ rejects the testcase.) Fixed by checking if process_outer_var_ref returned a capture. gcc/cp/ChangeLog: * reflect.cc (check_splice_expr): Check if process_outer_var_ref returned a capture, and give an error if so. gcc/testsuite/ChangeLog: * g++.dg/reflect/expr15.C: New test. Reviewed-by: Jason Merrill <[email protected]> Diff: --- gcc/cp/reflect.cc | 25 +++++++++++++------------ gcc/testsuite/g++.dg/reflect/expr15.C | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc index 2f9aa36c7872..bdeec2f0f38c 100644 --- a/gcc/cp/reflect.cc +++ b/gcc/cp/reflect.cc @@ -8395,20 +8395,21 @@ check_splice_expr (location_t loc, location_t start_loc, tree t, -- a local entity such that there is a lambda scope that intervenes between the expression and the point at which S was introduced" This also checks ODR violations (reflect/odr1.C). */ - if (outer_automatic_var_p (t) - && process_outer_var_ref (t, tf_none) == error_mark_node) - { - /* Not letting process_outer_var_ref emit the error so that we can - say "in a splice expression". */ - if (complain_p) + if (outer_automatic_var_p (t)) + if (tree r = process_outer_var_ref (t, tf_none)) + if (r == error_mark_node || is_capture_proxy (r)) { - auto_diagnostic_group d; - error_at (loc, "use of local variable with automatic storage from " - "containing function in a splice expression"); - inform (DECL_SOURCE_LOCATION (t), "%q#D declared here", t); + /* Not letting process_outer_var_ref emit the error so that we can + say "in a splice expression". */ + if (complain_p) + { + auto_diagnostic_group d; + error_at (loc, "use of local variable with automatic storage " + "from containing function in a splice expression"); + inform (DECL_SOURCE_LOCATION (t), "%q#D declared here", t); + } + return false; } - return false; - } /* If we had a reflect_kind here, we could just check for REFLECT_ANNOTATION and be done with it. But we don't have it yet (TODO), diff --git a/gcc/testsuite/g++.dg/reflect/expr15.C b/gcc/testsuite/g++.dg/reflect/expr15.C new file mode 100644 index 000000000000..41da34f00f02 --- /dev/null +++ b/gcc/testsuite/g++.dg/reflect/expr15.C @@ -0,0 +1,22 @@ +// { dg-do compile { target c++26 } } +// { dg-additional-options "-freflection" } + +void +f1 () +{ + int x = 1; // { dg-message ".x. declared here" } + constexpr auto r = ^^x; + [=] -> decltype(x) { + return [:r:]; // { dg-error "use of local variable" } + }; +} + +void +f2 () +{ + int x = 1; // { dg-message ".x. declared here" } + constexpr auto r = ^^x; + [&] -> decltype(x) { + return [:r:]; // { dg-error "use of local variable" } + }; +}
