diff options
author | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2025-09-02 15:58:26 -0700 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2025-09-02 15:58:26 -0700 |
commit | 071b4126c613881f4cb25b4e5c39032964827f88 (patch) | |
tree | 7ed805786566918630d1d617b1ed8f7310f5fd8e /gcc/cp/lambda.cc | |
parent | 845d23f3ea08ba873197c275a8857eee7edad996 (diff) | |
parent | caa1c2f42691d68af4d894a5c3e700ecd2dba080 (diff) | |
download | gcc-devel/gfortran-test.zip gcc-devel/gfortran-test.tar.gz gcc-devel/gfortran-test.tar.bz2 |
Merge branch 'master' into gfortran-testdevel/gfortran-test
Diffstat (limited to 'gcc/cp/lambda.cc')
-rw-r--r-- | gcc/cp/lambda.cc | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index ecf55eb..711e3b7 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -409,10 +409,11 @@ lambda_proxy_type (tree ref) /* MEMBER is a capture field in a lambda closure class. Now that we're inside the operator(), build a placeholder var for future lookups and - debugging. */ + debugging. But if EARLY_P is true, we do not have the real operator() + yet and we have to proceed differently. */ -static tree -build_capture_proxy (tree member, tree init) +tree +build_capture_proxy (tree member, tree init, bool early_p) { tree var, object, fn, closure, name, lam, type; @@ -503,11 +504,19 @@ build_capture_proxy (tree member, tree init) if (name == this_identifier) { + if (early_p) + return var; gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (lam) == member); LAMBDA_EXPR_THIS_CAPTURE (lam) = var; } - if (fn == current_function_decl) + if (early_p) + { + gcc_checking_assert (current_binding_level->kind == sk_lambda); + /* insert_capture_proxy below wouldn't push into the lambda scope. */ + pushdecl (var); + } + else if (fn == current_function_decl) insert_capture_proxy (var); else vec_safe_push (LAMBDA_EXPR_PENDING_PROXIES (lam), var); @@ -727,7 +736,7 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, = tree_cons (listmem, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda)); if (LAMBDA_EXPR_CLOSURE (lambda)) - return build_capture_proxy (member, initializer); + return build_capture_proxy (member, initializer, /*early_p=*/false); /* For explicit captures we haven't started the function yet, so we wait and build the proxy from cp_parser_lambda_body. */ LAMBDA_CAPTURE_EXPLICIT_P (LAMBDA_EXPR_CAPTURE_LIST (lambda)) = true; @@ -980,10 +989,14 @@ resolvable_dummy_lambda (tree object) tree type = TYPE_MAIN_VARIANT (TREE_TYPE (object)); gcc_assert (!TYPE_PTR_P (type)); + tree fn; if (type != current_class_type && current_class_type && LAMBDA_TYPE_P (current_class_type) - && lambda_function (current_class_type) + && (fn = lambda_function (current_class_type)) + /* Even dummy lambdas have an operator() since P2036, but the + dummy operator() doesn't have this set. */ + && DECL_LAMBDA_FUNCTION_P (fn) && DERIVED_FROM_P (type, nonlambda_method_basetype())) return CLASSTYPE_LAMBDA_EXPR (current_class_type); @@ -1038,13 +1051,19 @@ maybe_generic_this_capture (tree object, tree fns) } } -/* Returns the innermost non-lambda function. */ +/* Returns the innermost non-lambda function. If ONLY_SKIP_CONSTEVAL_BLOCK_P, + we only skip lambda functions that represent consteval blocks. */ tree -current_nonlambda_function (void) +current_nonlambda_function (bool only_skip_consteval_block_p/*=false*/) { tree fn = current_function_decl; - while (fn && LAMBDA_FUNCTION_P (fn)) + tree lam; + while (fn && LAMBDA_FUNCTION_P (fn) + && (!only_skip_consteval_block_p + /* Only keep going if FN represents a consteval block. */ + || ((lam = CLASSTYPE_LAMBDA_EXPR (CP_DECL_CONTEXT (fn))) + && LAMBDA_EXPR_CONSTEVAL_BLOCK_P (lam)))) fn = decl_function_context (fn); return fn; } @@ -1778,6 +1797,17 @@ record_lambda_scope_sig_discriminator (tree lambda, tree fn) LAMBDA_EXPR_SCOPE_SIG_DISCRIMINATOR (lambda) = sig->count++; } +/* Push the proxies for any explicit captures in LAMBDA_EXPR. + If EARLY_P, we do not have the real operator() yet. */ + +void +push_capture_proxies (tree lambda_expr, bool early_p) +{ + for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); cap; + cap = TREE_CHAIN (cap)) + build_capture_proxy (TREE_PURPOSE (cap), TREE_VALUE (cap), early_p); +} + tree start_lambda_function (tree fco, tree lambda_expr) { @@ -1790,9 +1820,7 @@ start_lambda_function (tree fco, tree lambda_expr) tree body = begin_function_body (); /* Push the proxies for any explicit captures. */ - for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); cap; - cap = TREE_CHAIN (cap)) - build_capture_proxy (TREE_PURPOSE (cap), TREE_VALUE (cap)); + push_capture_proxies (lambda_expr); return body; } |