commit: b5d57636befce566cec78c6cd26f400558d024e9 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Mon Aug 18 23:52:24 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Mon Aug 18 23:52:24 2025 +0000 URL: https://gitweb.gentoo.org/proj/gcc-patches.git/commit/?id=b5d57636
16.0.0: revert C++ lambda change It breaks building Dolphin, FF, ... Bug: https://gcc.gnu.org/PR121553 Signed-off-by: Sam James <sam <AT> gentoo.org> ...036R3-Change-scope-of-lambda-trailing-ret.patch | 1186 ++++++++++++++++++++ 16.0.0/gentoo/README.history | 4 + 2 files changed, 1190 insertions(+) diff --git a/16.0.0/gentoo/87_all_PR121553-Revert-c-P2036R3-Change-scope-of-lambda-trailing-ret.patch b/16.0.0/gentoo/87_all_PR121553-Revert-c-P2036R3-Change-scope-of-lambda-trailing-ret.patch new file mode 100644 index 0000000..ad792d0 --- /dev/null +++ b/16.0.0/gentoo/87_all_PR121553-Revert-c-P2036R3-Change-scope-of-lambda-trailing-ret.patch @@ -0,0 +1,1186 @@ +From 358ad796de168eedb8bcf9509a7dc40861f057a0 Mon Sep 17 00:00:00 2001 +Message-ID: <358ad796de168eedb8bcf9509a7dc40861f057a0.1755561114.git....@gentoo.org> +From: Sam James <[email protected]> +Date: Tue, 19 Aug 2025 00:51:27 +0100 +Subject: [PATCH] Revert "c++: P2036R3 - Change scope of lambda + trailing-return-type [PR102610]" + +This reverts commit d2dccd1bf79b862b9989c1b62ed8c074980cd457. + +Bug: https://gcc.gnu.org/PR121553 +--- + gcc/cp/cp-tree.h | 11 - + gcc/cp/lambda.cc | 40 +--- + gcc/cp/name-lookup.cc | 11 +- + gcc/cp/name-lookup.h | 1 - + gcc/cp/parser.cc | 94 -------- + gcc/cp/pt.cc | 21 -- + gcc/cp/semantics.cc | 64 ++---- + .../g++.dg/cpp0x/lambda/lambda-decltype3.C | 2 +- + gcc/testsuite/g++.dg/cpp23/lambda-scope1.C | 85 ------- + gcc/testsuite/g++.dg/cpp23/lambda-scope2.C | 217 ------------------ + gcc/testsuite/g++.dg/cpp23/lambda-scope3.C | 44 ---- + gcc/testsuite/g++.dg/cpp23/lambda-scope4.C | 41 ---- + gcc/testsuite/g++.dg/cpp23/lambda-scope4b.C | 42 ---- + gcc/testsuite/g++.dg/cpp23/lambda-scope5.C | 22 -- + gcc/testsuite/g++.dg/cpp23/lambda-scope6.C | 20 -- + gcc/testsuite/g++.dg/cpp23/lambda-scope7.C | 20 -- + gcc/testsuite/g++.dg/cpp23/lambda-scope8.C | 25 -- + gcc/testsuite/g++.dg/cpp23/lambda-scope9.C | 15 -- + gcc/testsuite/g++.dg/warn/Wshadow-19.C | 4 +- + gcc/testsuite/g++.dg/warn/Wshadow-6.C | 8 +- + 20 files changed, 37 insertions(+), 750 deletions(-) + delete mode 100644 gcc/testsuite/g++.dg/cpp23/lambda-scope1.C + delete mode 100644 gcc/testsuite/g++.dg/cpp23/lambda-scope2.C + delete mode 100644 gcc/testsuite/g++.dg/cpp23/lambda-scope3.C + delete mode 100644 gcc/testsuite/g++.dg/cpp23/lambda-scope4.C + delete mode 100644 gcc/testsuite/g++.dg/cpp23/lambda-scope4b.C + delete mode 100644 gcc/testsuite/g++.dg/cpp23/lambda-scope5.C + delete mode 100644 gcc/testsuite/g++.dg/cpp23/lambda-scope6.C + delete mode 100644 gcc/testsuite/g++.dg/cpp23/lambda-scope7.C + delete mode 100644 gcc/testsuite/g++.dg/cpp23/lambda-scope8.C + delete mode 100644 gcc/testsuite/g++.dg/cpp23/lambda-scope9.C + +diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h +index 55e8e0736272..d29d996e55e5 100644 +--- a/gcc/cp/cp-tree.h ++++ b/gcc/cp/cp-tree.h +@@ -476,7 +476,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; + ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P (in ATOMIC_CONSTR) + STATIC_INIT_DECOMP_BASE_P (in the TREE_LIST for {static,tls}_aggregates) + MUST_NOT_THROW_THROW_P (in MUST_NOT_THROW_EXPR) +- LAMBDA_EXPR_CONST_QUAL_P (in LAMBDA_EXPR) + 2: IDENTIFIER_KIND_BIT_2 (in IDENTIFIER_NODE) + ICS_THIS_FLAG (in _CONV) + DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL) +@@ -1558,13 +1557,6 @@ enum cp_lambda_default_capture_mode_type { + #define LAMBDA_EXPR_CONSTEVAL_BLOCK_P(NODE) \ + TREE_LANG_FLAG_0 (LAMBDA_EXPR_CHECK (NODE)) + +-/* True if we should add "const" when figuring out the type of an entity +- in a lambda. This is false in the parameter-declaration-clause of +- a lambda; after that, it will remain false if the mutable keyword is +- present. */ +-#define LAMBDA_EXPR_CONST_QUAL_P(NODE) \ +- TREE_LANG_FLAG_1 (LAMBDA_EXPR_CHECK (NODE)) +- + /* True iff uses of a const variable capture were optimized away. */ + #define LAMBDA_EXPR_CAPTURE_OPTIMIZED(NODE) \ + TREE_LANG_FLAG_2 (LAMBDA_EXPR_CHECK (NODE)) +@@ -7807,8 +7799,6 @@ extern location_t defparse_location (tree); + extern void maybe_show_extern_c_location (void); + extern bool literal_integer_zerop (const_tree); + extern tree attr_chainon (tree, tree); +-extern tree maybe_add_dummy_lambda_op (tree); +-extern void remove_dummy_lambda_op (tree, tree); + + /* in pt.cc */ + extern tree canonical_type_parameter (tree); +@@ -8339,7 +8329,6 @@ extern void record_lambda_scope (tree lambda); + extern void record_lambda_scope_discriminator (tree lambda); + extern void record_lambda_scope_sig_discriminator (tree lambda, tree fn); + extern tree start_lambda_function (tree fn, tree lambda_expr); +-extern void push_capture_proxies (tree, bool = false); + extern void finish_lambda_function (tree body); + extern bool regenerated_lambda_fn_p (tree); + extern tree lambda_regenerating_args (tree); +diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc +index 711e3b7a18e4..c798967f8e1c 100644 +--- a/gcc/cp/lambda.cc ++++ b/gcc/cp/lambda.cc +@@ -409,11 +409,10 @@ 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. But if EARLY_P is true, we do not have the real operator() +- yet and we have to proceed differently. */ ++ debugging. */ + +-tree +-build_capture_proxy (tree member, tree init, bool early_p) ++static tree ++build_capture_proxy (tree member, tree init) + { + tree var, object, fn, closure, name, lam, type; + +@@ -504,19 +503,11 @@ build_capture_proxy (tree member, tree init, bool early_p) + + if (name == this_identifier) + { +- if (early_p) +- return var; + gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (lam) == member); + LAMBDA_EXPR_THIS_CAPTURE (lam) = var; + } + +- 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) ++ if (fn == current_function_decl) + insert_capture_proxy (var); + else + vec_safe_push (LAMBDA_EXPR_PENDING_PROXIES (lam), var); +@@ -736,7 +727,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, /*early_p=*/false); ++ return build_capture_proxy (member, initializer); + /* 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; +@@ -989,14 +980,10 @@ 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) +- && (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) ++ && lambda_function (current_class_type) + && DERIVED_FROM_P (type, nonlambda_method_basetype())) + return CLASSTYPE_LAMBDA_EXPR (current_class_type); + +@@ -1797,17 +1784,6 @@ 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) + { +@@ -1820,7 +1796,9 @@ start_lambda_function (tree fco, tree lambda_expr) + tree body = begin_function_body (); + + /* Push the proxies for any explicit captures. */ +- push_capture_proxies (lambda_expr); ++ for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (lambda_expr); cap; ++ cap = TREE_CHAIN (cap)) ++ build_capture_proxy (TREE_PURPOSE (cap), TREE_VALUE (cap)); + + return body; + } +diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc +index fa367214507e..a805f42f6668 100644 +--- a/gcc/cp/name-lookup.cc ++++ b/gcc/cp/name-lookup.cc +@@ -3351,11 +3351,8 @@ check_local_shadow (tree decl) + } + /* Don't complain if it's from an enclosing function. */ + else if (DECL_CONTEXT (old) == current_function_decl +- && ((TREE_CODE (decl) != PARM_DECL +- && TREE_CODE (old) == PARM_DECL) +- /* We should also give an error for +- [x=1]{ int x; } */ +- || is_capture_proxy (old))) ++ && TREE_CODE (decl) != PARM_DECL ++ && TREE_CODE (old) == PARM_DECL) + { + /* Go to where the parms should be and see if we find + them there. */ +@@ -4641,8 +4638,7 @@ cp_binding_level_descriptor (cp_binding_level *scope) + "template-parameter-scope", + "template-explicit-spec-scope", + "transaction-scope", +- "openmp-scope", +- "lambda-scope" ++ "openmp-scope" + }; + static_assert (ARRAY_SIZE (scope_kind_names) == sk_count, + "must keep names aligned with scope_kind enum"); +@@ -4734,7 +4730,6 @@ begin_scope (scope_kind kind, tree entity) + case sk_transaction: + case sk_omp: + case sk_stmt_expr: +- case sk_lambda: + scope->keep = keep_next_level_flag; + break; + +diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h +index 5b142e748999..6a3c0df47007 100644 +--- a/gcc/cp/name-lookup.h ++++ b/gcc/cp/name-lookup.h +@@ -215,7 +215,6 @@ enum scope_kind { + "template <>", this scope is always empty. */ + sk_transaction, /* A synchronized or atomic statement. */ + sk_omp, /* An OpenMP structured block. */ +- sk_lambda, /* A lambda scope. */ + sk_count /* Number of scope_kind enumerations. */ + }; + +diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc +index d66b658b748f..9dbd254dc61b 100644 +--- a/gcc/cp/parser.cc ++++ b/gcc/cp/parser.cc +@@ -11887,10 +11887,6 @@ cp_parser_lambda_expression (cp_parser* parser, + if (cp_parser_start_tentative_firewall (parser)) + start = token; + +- /* A lambda scope starts immediately after the lambda-introducer of E +- and extends to the end of the compound-statement of E. */ +- begin_scope (sk_lambda, NULL_TREE); +- + ok &= cp_parser_lambda_declarator_opt (parser, lambda_expr, + consteval_block_p); + +@@ -11912,8 +11908,6 @@ cp_parser_lambda_expression (cp_parser* parser, + if (ok) + maybe_add_lambda_conv_op (type); + +- /* Leave the lambda scope. */ +- pop_bindings_and_leave_scope (); + finish_struct (type, /*attributes=*/NULL_TREE); + + in_expansion_stmt = save_in_expansion_stmt; +@@ -12305,13 +12299,6 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr, + clear_decl_specs (&lambda_specs); + /* A lambda op() is const unless explicitly 'mutable'. */ + cp_cv_quals quals = TYPE_QUAL_CONST; +- /* Don't add "const" to entities in the parameter-declaration-clause. */ +- LAMBDA_EXPR_CONST_QUAL_P (lambda_expr) = false; +- +- /* Inject the captures into the lambda scope as they may be used in the +- declarator and we have to be able to look them up. */ +- tree dummy_fco = maybe_add_dummy_lambda_op (lambda_expr); +- push_capture_proxies (lambda_expr, /*early_p=*/true); + + /* The template-parameter-list is optional, but must begin with + an opening angle if present. */ +@@ -12502,10 +12489,6 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr, + } + } + +- /* Now we're done with the parameter-declaration-clause, and should +- assume "const" unless "mutable" was present. */ +- LAMBDA_EXPR_CONST_QUAL_P (lambda_expr) = quals == TYPE_QUAL_CONST; +- + tx_qual = cp_parser_tx_qualifier_opt (parser); + if (omitted_parms_loc && tx_qual) + { +@@ -12563,10 +12546,6 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr, + pop_bindings_and_leave_scope (); + } + +- /* We are about to create the real operator(), so get rid of the old one. */ +- if (dummy_fco) +- remove_dummy_lambda_op (dummy_fco, lambda_expr); +- + /* Create the function call operator. + + Messing with declarators like this is no uglier than building up the +@@ -12646,79 +12625,6 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr, + } + } + +-/* Create a fake operator() for a lambda. We do this so that we can +- build_capture_proxy even before start_lambda_function. */ +- +-static tree +-make_dummy_lambda_op () +-{ +- cp_decl_specifier_seq return_type_specs; +- cp_cv_quals quals = TYPE_UNQUALIFIED; +- +- clear_decl_specs (&return_type_specs); +- return_type_specs.type = make_auto (); +- +- void *p = obstack_alloc (&declarator_obstack, 0); +- +- cp_declarator *declarator = make_id_declarator (NULL_TREE, +- call_op_identifier, +- sfk_none, +- input_location); +- +- declarator = make_call_declarator (declarator, void_list_node, quals, +- VIRT_SPEC_UNSPECIFIED, +- REF_QUAL_NONE, NULL_TREE, +- NULL_TREE, NULL_TREE, NULL_TREE, +- NULL_TREE, UNKNOWN_LOCATION); +- +- tree fco = grokmethod (&return_type_specs, declarator, NULL_TREE); +- obstack_free (&declarator_obstack, p); +- +- return fco; +-} +- +-/* We need to push early capture proxies (for parsing the lambda-declarator), +- and we may need a dummy operator() to be able to build the proxies. +- LAMBDA_EXPR is the lambda we are building the captures for. */ +- +-tree +-maybe_add_dummy_lambda_op (tree lambda_expr) +-{ +- /* If there are no captures, we don't need this. */ +- if (!LAMBDA_EXPR_CAPTURE_LIST (lambda_expr)) +- return NULL_TREE; +- +- tree fco = make_dummy_lambda_op (); +- if (fco != error_mark_node) +- finish_member_declaration (fco); +- +- return fco; +-} +- +-/* Remove the dummy operator() DUMMY_FCO we built for parsing the +- lambda-declarator of LAMBDA_EXPR. */ +- +-void +-remove_dummy_lambda_op (tree dummy_fco, tree lambda_expr) +-{ +- tree type = TREE_TYPE (lambda_expr); +- if (TYPE_FIELDS (type) == dummy_fco) +- { +- /* Stitch out the dummy operator(). */ +- TYPE_FIELDS (type) = DECL_CHAIN (TYPE_FIELDS (type)); +- /* And clear the member vector as well. */ +- auto *member_vec = CLASSTYPE_MEMBER_VEC (type); +- gcc_assert (member_vec->length () == 1); +- member_vec->truncate (0); +- } +- /* Class templates will have the dummy operator() stashed here too. */ +- tree &list = CLASSTYPE_DECL_LIST (type); +- if (list && TREE_VALUE (list) == dummy_fco) +- list = TREE_CHAIN (list); +- /* ??? We can't ggc_free dummy_fco yet. There's still a binding in the +- closure to it, and the captures have it as their DECL_CONTEXT. */ +-} +- + /* Parse the body of a lambda expression, which is simply + + compound-statement +diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc +index bb2d0b48fd42..b72f285d86d6 100644 +--- a/gcc/cp/pt.cc ++++ b/gcc/cp/pt.cc +@@ -20590,18 +20590,6 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) + + tree fntype = static_fn_type (oldfn); + +- begin_scope (sk_lambda, NULL_TREE); +- +- /* Like in cp_parser_lambda_expression, we need to bring the captures +- into the lambda scope. */ +- tree ns = decl_namespace_context (type); +- push_nested_namespace (ns); +- push_nested_class (type); +- tree dummy_fco = maybe_add_dummy_lambda_op (r); +- pop_nested_class (); +- pop_nested_namespace (ns); +- push_capture_proxies (r, /*early_p=*/true); +- + tree saved_ctp = current_template_parms; + if (oldtmpl) + { +@@ -20615,10 +20603,6 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) + --processing_template_decl; + } + +- /* We are about to create the real operator(), so get rid of the old one. */ +- if (dummy_fco) +- remove_dummy_lambda_op (dummy_fco, r); +- + if (fntype == error_mark_node) + r = error_mark_node; + else +@@ -20652,10 +20636,6 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) + enclosing expression. */ + cp_evaluated ev; + +- /* Now we're done with the parameter-declaration-clause, and should +- assume "const" unless "mutable" was present. */ +- LAMBDA_EXPR_CONST_QUAL_P (r) = LAMBDA_EXPR_CONST_QUAL_P (t); +- + bool nested = cfun; + if (nested) + push_function_context (); +@@ -20724,7 +20704,6 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) + } + + out: +- pop_bindings_and_leave_scope (); + finish_struct (type, /*attr*/NULL_TREE); + + insert_pending_capture_proxies (); +diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc +index 26709c7a33bf..ef331f64f8da 100644 +--- a/gcc/cp/semantics.cc ++++ b/gcc/cp/semantics.cc +@@ -4511,17 +4511,6 @@ baselink_for_fns (tree fns) + return build_baselink (conv_path, access_path, fns, /*optype=*/NULL_TREE); + } + +-/* Returns true iff we are currently parsing a lambda-declarator. */ +- +-static bool +-parsing_lambda_declarator () +-{ +- cp_binding_level *b = current_binding_level; +- while (b->kind == sk_template_parms || b->kind == sk_function_parms) +- b = b->level_chain; +- return b->kind == sk_lambda; +-} +- + /* Returns true iff DECL is a variable from a function outside + the current one. */ + +@@ -4536,15 +4525,7 @@ outer_var_p (tree decl) + /* Don't get confused by temporaries. */ + && DECL_NAME (decl) + && (DECL_CONTEXT (decl) != current_function_decl +- || parsing_nsdmi () +- /* Also consider captures as outer vars if we are in +- decltype in a lambda declarator as in: +- auto l = [j=0]() -> decltype((j)) { ... } +- for the sake of finish_decltype_type. +- +- (Similar issue also affects non-lambdas, but vexing parse +- makes it more difficult to handle than lambdas.) */ +- || parsing_lambda_declarator ())); ++ || parsing_nsdmi ())); + } + + /* As above, but also checks that DECL is automatic. */ +@@ -4590,7 +4571,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use) + if (!mark_used (decl, complain)) + return error_mark_node; + +- if (parsing_nsdmi () || parsing_lambda_declarator ()) ++ if (parsing_nsdmi ()) + containing_function = NULL_TREE; + + if (containing_function && LAMBDA_FUNCTION_P (containing_function)) +@@ -12960,9 +12941,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, + } + else + { +- tree decl = STRIP_REFERENCE_REF (expr); +- tree lam = current_lambda_expr (); +- if (lam && outer_automatic_var_p (decl)) ++ if (outer_automatic_var_p (STRIP_REFERENCE_REF (expr)) ++ && current_function_decl ++ && LAMBDA_FUNCTION_P (current_function_decl)) + { + /* [expr.prim.id.unqual]/3: If naming the entity from outside of an + unevaluated operand within S would refer to an entity captured by +@@ -12979,6 +12960,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, + local variable inside decltype, not just decltype((x)) (PR83167). + And we don't handle nested lambdas properly, where we need to + consider the outer lambdas as well (PR112926). */ ++ tree decl = STRIP_REFERENCE_REF (expr); ++ tree lam = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (current_function_decl)); + tree cap = lookup_name (DECL_NAME (decl), LOOK_where::BLOCK, + LOOK_want::HIDDEN_LAMBDA); + +@@ -12994,28 +12977,17 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, + + if (type && !TYPE_REF_P (type)) + { +- int quals; +- if (current_function_decl +- && LAMBDA_FUNCTION_P (current_function_decl) +- && DECL_XOBJ_MEMBER_FUNCTION_P (current_function_decl)) +- { +- tree obtype = TREE_TYPE (DECL_ARGUMENTS (current_function_decl)); +- if (WILDCARD_TYPE_P (non_reference (obtype))) +- /* We don't know what the eventual obtype quals will be. */ +- goto dependent; +- auto direct_type = [](tree t){ +- if (INDIRECT_TYPE_P (t)) +- return TREE_TYPE (t); +- return t; +- }; +- quals = (cp_type_quals (type) +- | cp_type_quals (direct_type (obtype))); +- } +- else +- /* We are in the parameter clause, trailing return type, or +- the requires clause and have no relevant c_f_decl yet. */ +- quals = (LAMBDA_EXPR_CONST_QUAL_P (lam) +- ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED); ++ tree obtype = TREE_TYPE (DECL_ARGUMENTS (current_function_decl)); ++ if (WILDCARD_TYPE_P (non_reference (obtype))) ++ /* We don't know what the eventual obtype quals will be. */ ++ goto dependent; ++ auto direct_type = [](tree t){ ++ if (INDIRECT_TYPE_P (t)) ++ return TREE_TYPE (t); ++ return t; ++ }; ++ int const quals = cp_type_quals (type) ++ | cp_type_quals (direct_type (obtype)); + type = cp_build_qualified_type (type, quals); + type = build_reference_type (type); + } +diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype3.C +index 6ba0dabc37d5..2e06e4961408 100644 +--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype3.C ++++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-decltype3.C +@@ -11,7 +11,7 @@ void f() { + decltype((x)) y2 = y1; // y2 has type float const& + decltype(r) r1 = y1; // r1 has type float& + decltype((r)) r2 = y2; // r2 has type float const& +- return y2; // { dg-bogus "'float&' to 'const float'" } ++ return y2; // { dg-bogus "'float&' to 'const float'" "" { xfail *-*-* } } + }; + + [=](decltype((x)) y) { +diff --git a/gcc/testsuite/g++.dg/cpp23/lambda-scope1.C b/gcc/testsuite/g++.dg/cpp23/lambda-scope1.C +deleted file mode 100644 +index 000979e30778..000000000000 +--- a/gcc/testsuite/g++.dg/cpp23/lambda-scope1.C ++++ /dev/null +@@ -1,85 +0,0 @@ +-// P2036R3 - Change scope of lambda trailing-return-type +-// PR c++/102610 +-// { dg-do compile { target c++23 } } +- +-template <typename T, typename U> +-constexpr bool is_same = false; +- +-template <typename T> +-constexpr bool is_same<T, T> = true; +- +-struct S { +- void foo () { +- auto counter1 = [j=0]() mutable -> decltype(j) { +- return j++; +- }; +- auto counter2 = [j=0, o=0, k=0, e=0]() mutable -> decltype(j) { +- return j + o + k + e; +- }; +- } +-}; +- +-// [expr.prim.id.unqual]/3.2 +-void +-f () +-{ +- float x, &r = x; +- +- [=]() -> decltype((x)) { // lambda returns float const& because this lambda is not mutable and +- // x is an lvalue +- decltype(x) y1; // y1 has type float +- decltype((x)) y2 = y1; // y2 has type float const& +- decltype(r) r1 = y1; // r1 has type float& +- decltype((r)) r2 = y2; // r2 has type float const& +- return y2; +- }; +- +- [=](decltype((x)) y) { +- decltype((x)) z = x; // OK, y has type float&, z has type float const& +- static_assert(is_same<float&, decltype((y))>); +- static_assert(is_same<const float&, decltype((z))>); +- }; +- +- [=] { +- [](decltype((x)) y) { // OK, lambda takes a parameter of type float const& +- }; +- +- [x=1](decltype((x)) y) { +- decltype((x)) z = x; // OK, y has type int&, z has type int const& +- // FIXME We don't handle nested lambdas yet? +- //static_assert(is_same<int&, decltype((y))>); +- static_assert(is_same<const int&, decltype((z))>); +- }; +- }; +- +- [x=1](decltype((x)) y) { +- decltype((x)) z = x; +- static_assert(is_same<int&, decltype((y))>); +- static_assert(is_same<const int&, decltype((z))>); +- }; +-} +- +-void +-ok () +-{ +- auto counter1 = [j=0]() mutable -> decltype(j) { +- static_assert(is_same<int&, decltype((j))>); +- return j++; +- }; +- +- auto l = [j=0]() -> decltype(j) { +- static_assert(is_same<const int&, decltype((j))>); +- return j; +- }; +- +- int y; +- [=] -> decltype((y)) { +- return y; +- }; +-} +- +-void +-foo () +-{ +- int x = [x](int y[sizeof x]){return sizeof x;}(0); +-} +diff --git a/gcc/testsuite/g++.dg/cpp23/lambda-scope2.C b/gcc/testsuite/g++.dg/cpp23/lambda-scope2.C +deleted file mode 100644 +index 6b55e5fe5134..000000000000 +--- a/gcc/testsuite/g++.dg/cpp23/lambda-scope2.C ++++ /dev/null +@@ -1,217 +0,0 @@ +-// P2036R3 - Change scope of lambda trailing-return-type +-// PR c++/102610 +-// { dg-do compile { target c++23 } } +-// From LLVM's test/SemaCXX/lambda-capture-type-deduction.cpp +- +-template <typename T, typename U> +-constexpr bool is_same = false; +- +-template <typename T> +-constexpr bool is_same<T, T> = true; +- +-void +-f () +-{ +- int y; +- +- static_assert(is_same<const int &, +- decltype([x = 1] -> decltype((x)) { return x; }())>); +- +- static_assert(is_same<int &, +- decltype([x = 1] mutable -> decltype((x)) { return x; }())>); +- +- static_assert(is_same<const int &, +- decltype([=] -> decltype((y)) { return y; }())>); +- +- static_assert(is_same<int &, +- decltype([=] mutable -> decltype((y)) { return y; }())>); +- +- // Clang++ rejects this one, though the only difference is the extra (), +- // and without the () the result is correct, as demonstrated above. +- static_assert(is_same<const int &, +- decltype([=]() -> decltype((y)) { return y; }())>); +- +- static_assert(is_same<int &, +- decltype([=]() mutable -> decltype((y)) { return y; }())>); +- +- static_assert(is_same<const int &, +- decltype([y] -> decltype((y)) { return y; }())>); +- +- static_assert(is_same<int &, +- decltype([y] mutable -> decltype((y)) { return y; }())>); +- +- +- auto ref = [&x = y]( +- decltype([&](decltype(x)) { return 0; }) y) { +- return x; +- }; +-} +- +-void +-nested () +-{ +- int x, y, z; +- (void)[&]( +- decltype([&]( +- decltype([=]( +- decltype([&]( +- decltype([&](decltype(x)) {})) {})) {})) {})){}; +- +- (void)[&]( +- decltype([&]( +- decltype([&]( +- decltype([&]( +- decltype([&](decltype(y)) {})) {})) {})) {})){}; +- +- (void)[=]( +- decltype([=]( +- decltype([=]( +- decltype([=]( +- decltype([&]<decltype(z)> {})) {})) {})) {})){}; +-} +- +-void +-test_noexcept () +-{ +- int y; +- +- static_assert(noexcept([x = 1] noexcept(is_same<const int &, decltype((x))>) {}())); +- static_assert(noexcept([x = 1] mutable noexcept(is_same<int &, decltype((x))>) {}())); +- static_assert(noexcept([y] noexcept(is_same<const int &, decltype((y))>) {}())); +- static_assert(noexcept([y] mutable noexcept(is_same<int &, decltype((y))>) {}())); +- static_assert(noexcept([=] noexcept(is_same<const int &, decltype((y))>) {}())); +- static_assert(noexcept([=] mutable noexcept(is_same<int &, decltype((y))>) {}())); +- static_assert(noexcept([&] noexcept(is_same<int &, decltype((y))>) {}())); +- static_assert(noexcept([&] mutable noexcept(is_same<int &, decltype((y))>) {}())); +-} +- +-void +-check_params () +-{ +- int i = 0; +- int &j = i; +- +- [=](decltype((j)) jp, decltype((i)) ip) { +- static_assert(is_same<const int&, decltype((j))>); +- static_assert(is_same<const int &, decltype((i))>); +- static_assert(is_same<int &, decltype((jp))>); +- static_assert(is_same<int &, decltype((ip))>); +- }; +- +- [=](decltype((j)) jp, decltype((i)) ip) mutable { +- static_assert(is_same<int &, decltype((j))>); +- static_assert(is_same<int &, decltype((i))>); +- static_assert(is_same<int &, decltype((jp))>); +- static_assert(is_same<int &, decltype((ip))>); +- static_assert(is_same<int &, decltype(jp)>); +- static_assert(is_same<int &, decltype(ip)>); +- }; +- +- [a = 0](decltype((a)) ap) mutable { +- static_assert(is_same<int &, decltype((a))>); +- static_assert(is_same<int, decltype(a)>); +- static_assert(is_same<int &, decltype(ap)>); +- decltype(a) x; +- decltype((a)) y = x; +- static_assert(is_same<int &, decltype(y)>); +- }; +- +- [a = 0](decltype((a)) ap) { +- static_assert(is_same<const int &, decltype((a))>); +- static_assert(is_same<int, decltype(a)>); +- static_assert(is_same<int&, decltype((ap))>); +- decltype(a) x; +- decltype((a)) y = x; +- static_assert(is_same<const int &, decltype(y)>); +- }; +- +- int a; +- [a](decltype((a)) ap) mutable { +- static_assert(is_same<int &, decltype((a))>); +- static_assert(is_same<int, decltype(a)>); +- static_assert(is_same<int &, decltype(ap)>); +- decltype(a) x; +- decltype((a)) y = x; +- static_assert(is_same<int &, decltype(y)>); +- }; +- +- [a](decltype((a)) ap) { +- static_assert(is_same<const int &, decltype((a))>); +- static_assert(is_same<int, decltype(a)>); +- static_assert(is_same<int&, decltype((ap))>); +- decltype(a) x; +- decltype((a)) y = x; +- static_assert(is_same<const int &, decltype(y)>); +- }; +-} +- +-template <typename T> +-void +-check_params_tpl () +-{ +- T i = 0; +- T &j = i; +- (void)[=](decltype((j)) jp, decltype((i)) ip) { +- static_assert(is_same<const int&, decltype((j))>); +- static_assert(is_same<const int &, decltype((i))>); +- // In these two, clang++ produces 'const int&'. Why, when it's +- // the same as in check_params, just not a template? +- static_assert(is_same<int &, decltype((jp))>); +- static_assert(is_same<int &, decltype((ip))>); +- }; +- +- (void)[=](decltype((j)) jp, decltype((i)) ip) mutable { +- static_assert(is_same<int &, decltype((j))>); +- static_assert(is_same<int &, decltype((i))>); +- static_assert(is_same<int &, decltype((jp))>); +- static_assert(is_same<int &, decltype((ip))>); +- static_assert(is_same<int &, decltype(jp)>); +- static_assert(is_same<int &, decltype(ip)>); +- }; +- +- (void)[a = 0](decltype((a)) ap) mutable { +- static_assert(is_same<int &, decltype((a))>); +- static_assert(is_same<int, decltype(a)>); +- static_assert(is_same<int &, decltype(ap)>); +- }; +- (void)[a = 0](decltype((a)) ap) { +- static_assert(is_same<const int &, decltype((a))>); +- static_assert(is_same<int, decltype(a)>); +- static_assert(is_same<int&, decltype((ap))>); +- }; +-} +- +-template<typename T> +-void +-test_requires () +-{ +- int x; +- +- [x = 1]() requires is_same<const int &, decltype((x))> {} (); +- [x = 1]() mutable requires is_same<int &, decltype((x))> {} +- (); +- [x]() requires is_same<const int &, decltype((x))> {} (); +- [x]() mutable requires is_same<int &, decltype((x))> {} +- (); +- [=]() requires is_same<const int &, decltype((x))> {} (); +- [=]() mutable requires is_same<int &, decltype((x))> {} +- (); +- [&]() requires is_same<int &, decltype((x))> {} +- (); +- [&]() mutable requires is_same<int &, decltype((x))> {} +- (); +- [&x]() requires is_same<int &, decltype((x))> {} +- (); +- [&x]() mutable requires is_same<int &, decltype((x))> {} +- (); +- +- [x = 1]() requires is_same<const int &, decltype((x))> {} (); +- [x = 1]() mutable requires is_same<int &, decltype((x))> {} (); +-} +- +-void +-use () +-{ +- test_requires<int>(); +- check_params_tpl<int>(); +-} +diff --git a/gcc/testsuite/g++.dg/cpp23/lambda-scope3.C b/gcc/testsuite/g++.dg/cpp23/lambda-scope3.C +deleted file mode 100644 +index 697fdaae0955..000000000000 +--- a/gcc/testsuite/g++.dg/cpp23/lambda-scope3.C ++++ /dev/null +@@ -1,44 +0,0 @@ +-// P2036R3 - Change scope of lambda trailing-return-type +-// PR c++/102610 +-// { dg-do compile { target c++17 } } +- +-template <typename T> +-inline constexpr auto +-equal1 (T &&t) +-{ +- return [t = 3](const auto& obj) -> decltype(obj == t) +- { +- return obj == t; +- }; +-} +- +-template <typename T> +-inline constexpr auto +-equal2 (T &&t) +-{ +- return [t = t](const auto& obj) -> decltype(obj == t) +- { +- return obj == t; +- }; +-} +- +-template <typename T> +-inline constexpr auto +-equal3 (T &&t) +-{ +- return [t = 4](const auto& obj) -> decltype(obj == t) +- { +- return obj == t; +- }; +-} +- +-void +-g () +-{ +- constexpr auto l1 = equal1 (5); +- static_assert (l1 (3)); +- constexpr auto l2 = equal2 (3); +- static_assert (l2 (3)); +- constexpr auto l3 = equal3 (2); +- static_assert (l3 (4)); +-} +diff --git a/gcc/testsuite/g++.dg/cpp23/lambda-scope4.C b/gcc/testsuite/g++.dg/cpp23/lambda-scope4.C +deleted file mode 100644 +index 9442db3f9567..000000000000 +--- a/gcc/testsuite/g++.dg/cpp23/lambda-scope4.C ++++ /dev/null +@@ -1,41 +0,0 @@ +-// P2036R3 - Change scope of lambda trailing-return-type +-// PR c++/102610 +-// { dg-do compile { target c++17 } } +- +-struct integral_constant { +- using type = integral_constant; +-}; +-template <bool> using __bool_constant = integral_constant; +-template <typename _Fn, typename> +-struct is_invocable : __bool_constant<true> {}; +-int forward() { return 42; } +-template <typename...> class tuple; +-struct plus { +- template <typename _Tp, typename _Up> +- constexpr auto operator()(_Tp __t, _Up __u) { +- return __t > __u; +- } +-}; +-constexpr auto equal() { +- int t = 0; +- return [t = 3](auto obj) -> decltype(obj == t) { return t; }; +-} +-template <typename> struct is_tuple_invocable; +-template <typename... Ts> struct is_tuple_invocable<tuple<Ts...>> { +- using type = typename is_invocable<Ts...>::type; +-}; +-namespace detail { +-template <typename F, typename Tail, typename... T> +-constexpr auto compose(__bool_constant<true>, F f, Tail tail, T... objs) { +- return f(tail(objs...)); +-} +-} // namespace detail +-template <typename F, typename... Fs> constexpr auto compose(F f, Fs... fs) { +- return [f, tail(fs...)](auto... objs) { +- auto unitail = +- typename is_tuple_invocable<tuple<decltype(objs)...>>::type{}; +- return detail::compose(unitail, f, tail, objs...); +- }; +-} +-template <auto> constexpr auto eq = equal(); +-static_assert(compose(eq<3>, plus{})(1, 2)); +diff --git a/gcc/testsuite/g++.dg/cpp23/lambda-scope4b.C b/gcc/testsuite/g++.dg/cpp23/lambda-scope4b.C +deleted file mode 100644 +index 6a9e6ec5e9d7..000000000000 +--- a/gcc/testsuite/g++.dg/cpp23/lambda-scope4b.C ++++ /dev/null +@@ -1,42 +0,0 @@ +-// P2036R3 - Change scope of lambda trailing-return-type +-// PR c++/102610 +-// { dg-do compile { target c++17 } } +- +-struct integral_constant { +- using type = integral_constant; +-}; +-template <bool> using __bool_constant = integral_constant; +-template <typename _Fn, typename> +-struct is_invocable : __bool_constant<true> {}; +-int forward() { return 42; } +-template <typename...> class tuple; +-struct plus { +- template <typename _Tp, typename _Up> +- constexpr auto operator()(_Tp __t, _Up __u) { +- return __t > __u; +- } +-}; +-constexpr auto equal() { +- int t = 0; +- return [t = 3](auto obj) -> decltype(obj == t) { return t; }; +-} +-template <typename> struct is_tuple_invocable; +-template <typename... Ts> struct is_tuple_invocable<tuple<Ts...>> { +- using type = typename is_invocable<Ts...>::type; +-}; +-namespace detail { +-template <typename F, typename Tail, typename... T> +-constexpr auto compose(__bool_constant<true>, F f, Tail tail, T... objs) { +- return f(tail(objs...)); +-} +-} // namespace detail +-template <typename F, typename... Fs> +-constexpr auto compose(F f, Fs... fs) { +- return [f, tail(fs...)](auto... objs) -> decltype (detail::compose(typename is_tuple_invocable<tuple<decltype(objs)...>>::type{}, f, tail, objs...)) { +- auto unitail = +- typename is_tuple_invocable<tuple<decltype(objs)...>>::type{}; +- return detail::compose(unitail, f, tail, objs...); +- }; +-} +-template <auto> constexpr auto eq = equal(); +-static_assert(compose(eq<3>, plus{})(1, 2)); +diff --git a/gcc/testsuite/g++.dg/cpp23/lambda-scope5.C b/gcc/testsuite/g++.dg/cpp23/lambda-scope5.C +deleted file mode 100644 +index 48b5ef34c9e9..000000000000 +--- a/gcc/testsuite/g++.dg/cpp23/lambda-scope5.C ++++ /dev/null +@@ -1,22 +0,0 @@ +-// P2036R3 - Change scope of lambda trailing-return-type +-// PR c++/102610 +-// { dg-do compile { target c++17 } } +- +-constexpr auto equal() { +- int t = 0; +- return [t](auto obj) { return obj; }; +-} +-template <typename F> +-constexpr int bar (F) { +- return 42; +-} +- +-template <typename F> +-constexpr auto compose(F f) +-{ +- return [f=f](int i) -> decltype(bar (f)) { +- return 42; +- }; +-} +-template <auto> constexpr auto eq = equal(); +-static_assert(compose(eq<3>)(1)); +diff --git a/gcc/testsuite/g++.dg/cpp23/lambda-scope6.C b/gcc/testsuite/g++.dg/cpp23/lambda-scope6.C +deleted file mode 100644 +index 720c1ec6cba2..000000000000 +--- a/gcc/testsuite/g++.dg/cpp23/lambda-scope6.C ++++ /dev/null +@@ -1,20 +0,0 @@ +-// P2036R3 - Change scope of lambda trailing-return-type +-// PR c++/102610 +-// { dg-do compile { target c++23 } } +- +-void +-g () +-{ +- /* It looks like this shouldn't work but [expr.prim.lambda.closure]/6 +- says "Otherwise, it is a non-static member function or member function +- template that is declared const if and only if the lambda-expression's +- parameter-declaration-clause is not followed by mutable and the +- lambda-declarator does not contain an explicit object parameter." */ +- auto counter = [j=0](this auto const& self) -> decltype(j) { +- return j++; +- }; +- +- auto counter2 = [j=0](this auto& self) -> decltype(j) { +- return j++; +- }; +-} +diff --git a/gcc/testsuite/g++.dg/cpp23/lambda-scope7.C b/gcc/testsuite/g++.dg/cpp23/lambda-scope7.C +deleted file mode 100644 +index 6db39bd8692c..000000000000 +--- a/gcc/testsuite/g++.dg/cpp23/lambda-scope7.C ++++ /dev/null +@@ -1,20 +0,0 @@ +-// P2036R3 - Change scope of lambda trailing-return-type +-// PR c++/102610 +-// { dg-do compile { target c++14_only } } +- +-template <typename T> +-inline constexpr auto +-equal1 (T &&t) +-{ +- return [t = 3](const auto& obj) -> decltype(obj == t) +- { +- return obj == t; +- }; +-} +- +-void +-g () +-{ +- constexpr auto l1 = equal1 (5); // { dg-error "not literal" } +- static_assert (l1 (3), ""); // { dg-error "non-constant|non-.constexpr." } +-} +diff --git a/gcc/testsuite/g++.dg/cpp23/lambda-scope8.C b/gcc/testsuite/g++.dg/cpp23/lambda-scope8.C +deleted file mode 100644 +index 87ad47323809..000000000000 +--- a/gcc/testsuite/g++.dg/cpp23/lambda-scope8.C ++++ /dev/null +@@ -1,25 +0,0 @@ +-// P2036R3 - Change scope of lambda trailing-return-type +-// PR c++/102610 +-// { dg-do compile { target c++23 } } +-// { dg-options "-Wshadow" } +- +-void +-bad () +-{ +- [x=1](int x){}; // { dg-error "declared as a capture" } +- // { dg-warning "shadows a lambda capture" "" { target *-*-* } .-1 } +- [x=1]{ int x; }; // { dg-error "shadows a parameter" } +- +- auto f = [i = 5] () { int i; return 0; }; // { dg-error "shadows a parameter" } +- auto f2 = [i = 5] <int N> () { int i; return 0; }; // { dg-error "shadows a parameter" } +- +- // [expr.prim.lambda.capture]/5 +- int x = 0; +- auto g = [x](int x) { return 0; }; // { dg-error "declared as a capture" } +- // { dg-warning "shadows a lambda capture" "" { target *-*-* } .-1 } +- auto h = [y = 0]<typename y>(y) { return 0; }; // { dg-error "shadows template parameter" } +- +- auto l2 = [i = 0, j = i]() -> decltype(i) { // { dg-error "not declared in this scope" } +- return i; +- }; +-} +diff --git a/gcc/testsuite/g++.dg/cpp23/lambda-scope9.C b/gcc/testsuite/g++.dg/cpp23/lambda-scope9.C +deleted file mode 100644 +index b75e97cb89d7..000000000000 +--- a/gcc/testsuite/g++.dg/cpp23/lambda-scope9.C ++++ /dev/null +@@ -1,15 +0,0 @@ +-// P2036R3 - Change scope of lambda trailing-return-type +-// PR c++/102610 +-// { dg-do compile { target c++23 } } +-// { dg-options "" } +- +-constexpr char f(auto a) { return 'a'; } +- +-namespace A { +- int i = 42; +- template<char X = f([i]{})> void g() { } // { dg-warning "capture of variable .A::i. with non-automatic storage duration" } +-} +- +-namespace B { +- void call() { A::g(); } +-} +diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-19.C b/gcc/testsuite/g++.dg/warn/Wshadow-19.C +index d0b8dba8549f..030aefd153d8 100644 +--- a/gcc/testsuite/g++.dg/warn/Wshadow-19.C ++++ b/gcc/testsuite/g++.dg/warn/Wshadow-19.C +@@ -1,5 +1,5 @@ + // { dg-do compile } +-// { dg-options "-Wshadow -Wpedantic" } ++// { dg-options "-Wshadow" } + + void + foo (int x) +@@ -10,7 +10,7 @@ foo (int x) + extern int y; // { dg-warning "declaration of 'y' shadows a previous local" } + } + #if __cplusplus >= 201102L +- auto fn = [x] () { extern int x; return 0; }; // { dg-warning "declaration of 'int x' shadows a parameter" "" { target c++11 } } ++ auto fn = [x] () { extern int x; return 0; }; // { dg-warning "declaration of 'x' shadows a lambda capture" "" { target c++11 } } + #endif + } + +diff --git a/gcc/testsuite/g++.dg/warn/Wshadow-6.C b/gcc/testsuite/g++.dg/warn/Wshadow-6.C +index 7b44d52781aa..1d8d21b9b6f1 100644 +--- a/gcc/testsuite/g++.dg/warn/Wshadow-6.C ++++ b/gcc/testsuite/g++.dg/warn/Wshadow-6.C +@@ -33,8 +33,8 @@ void f2(struct S i, int j) { + + void f3(int i) { + [=]{ +- int j = i; // { dg-message "previously declared here" } +- int i; // { dg-error "shadows a parameter" } ++ int j = i; // { dg-message "shadowed declaration" } ++ int i; // { dg-warning "shadows a lambda capture" } + i = 1; + }; + } +@@ -42,8 +42,8 @@ void f3(int i) { + template <class T> + void f4(int i) { + [=]{ +- int j = i; // { dg-message "previously declared here" } +- int i; // { dg-error "shadows a parameter" } ++ int j = i; // { dg-message "shadowed declaration" } ++ int i; // { dg-warning "shadows a " } + i = 1; + }; + } + +base-commit: 2be801a805c6cca08aaa33fd387dcc7bd4fe8aac +-- +2.51.0 + diff --git a/16.0.0/gentoo/README.history b/16.0.0/gentoo/README.history index dcb6159..b2fcc91 100644 --- a/16.0.0/gentoo/README.history +++ b/16.0.0/gentoo/README.history @@ -1,3 +1,7 @@ +11 ???? + + + 87_all_PR121553-Revert-c-P2036R3-Change-scope-of-lambda-trailing-ret.patch + 10 17 August 2025 + 86_all_PR121572_x86-Place-the-TLS-call-before-all-FLAGS_REG-setting-.patch
