c++, contracts: Account for lambda captures in pre/post [PR124648].
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
Commit Message
This is a second issue that appears once the exclusion of implicit
lambda captures is fixed. Tested on x86_64-darwin, powerpc64le-linux
OK for trunk/when?
thanks
Iain
--- 8< ---
When we have lambda captures, they appear in the vars slot of a bind
expression at the outer operator() body.
We need these to be visible for any pre or post conditions that might
use them, therefore (when a lambda has captures) nest the application
of contract pre and post conditions within the lambda outer bind
expression.
PR c++/124648
gcc/cp/ChangeLog:
* contracts.cc (maybe_apply_function_contracts): Nest pre and
post conditions inside the outer bind expression of a lambda
with captures.
Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
---
gcc/cp/contracts.cc | 12 ++++++++++++
1 file changed, 12 insertions(+)
Comments
On 4/8/26 5:53 AM, Iain Sandoe wrote:
> This is a second issue that appears once the exclusion of implicit
> lambda captures is fixed. Tested on x86_64-darwin, powerpc64le-linux
> OK for trunk/when?
> thanks
> Iain
>
> --- 8< ---
>
> When we have lambda captures, they appear in the vars slot of a bind
> expression at the outer operator() body.
>
> We need these to be visible for any pre or post conditions that might
> use them, therefore (when a lambda has captures) nest the application
> of contract pre and post conditions within the lambda outer bind
> expression.
>
> PR c++/124648
>
> gcc/cp/ChangeLog:
>
> * contracts.cc (maybe_apply_function_contracts): Nest pre and
> post conditions inside the outer bind expression of a lambda
> with captures.
>
> Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
> ---
> gcc/cp/contracts.cc | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/gcc/cp/contracts.cc b/gcc/cp/contracts.cc
> index d2dba3c62e6..760327d2020 100644
> --- a/gcc/cp/contracts.cc
> +++ b/gcc/cp/contracts.cc
> @@ -1352,6 +1352,18 @@ maybe_apply_function_contracts (tree fndecl)
> DECL_SAVED_TREE (fndecl) = push_stmt_list ();
> }
>
> + /* If we have a lambda with captures, ensure that those captures are in-
> + scope for pre and post conditions. */
> + if (LAMBDA_TYPE_P (CP_DECL_CONTEXT (fndecl))
This could be LAMBDA_FUNCTION_P. OK with that change.
> + && TREE_CODE (fnbody) == BIND_EXPR)
> + {
> + tree extract = BIND_EXPR_BODY (fnbody);
> + BIND_EXPR_BODY (fnbody) = NULL_TREE;
> + add_stmt (fnbody);
> + BIND_EXPR_BODY (fnbody) = push_stmt_list ();
> + fnbody = extract;
> + }
> +
> /* Now add the pre and post conditions to the existing function body.
> This copies the approach used for function try blocks. */
> tree compound_stmt = begin_compound_stmt (0);
@@ -1352,6 +1352,18 @@ maybe_apply_function_contracts (tree fndecl)
DECL_SAVED_TREE (fndecl) = push_stmt_list ();
}
+ /* If we have a lambda with captures, ensure that those captures are in-
+ scope for pre and post conditions. */
+ if (LAMBDA_TYPE_P (CP_DECL_CONTEXT (fndecl))
+ && TREE_CODE (fnbody) == BIND_EXPR)
+ {
+ tree extract = BIND_EXPR_BODY (fnbody);
+ BIND_EXPR_BODY (fnbody) = NULL_TREE;
+ add_stmt (fnbody);
+ BIND_EXPR_BODY (fnbody) = push_stmt_list ();
+ fnbody = extract;
+ }
+
/* Now add the pre and post conditions to the existing function body.
This copies the approach used for function try blocks. */
tree compound_stmt = begin_compound_stmt (0);