From: Marek Polacek Date: Thu, 22 Jan 2026 20:52:45 +0000 (-0500) Subject: c++/reflection: detect more invalid splices in lambda X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f3bf6e14360d7a6d5ecca494b94a2165a97ec34c;p=thirdparty%2Fgcc.git c++/reflection: detect more invalid splices in lambda The comment for check_splice_expr in 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 --- diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc index 2f9aa36c787..bdeec2f0f38 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 00000000000..41da34f00f0 --- /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" } + }; +}