https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70218
Patrick Palka <ppalka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ppalka at gcc dot gnu.org --- Comment #1 from Patrick Palka <ppalka at gcc dot gnu.org> --- struct X { private: int i; }; struct Y { Y (int) { } }; int main () { Y ([] { X x; x.i = 3; return 0; } ()); } We are mishandling the deferred_access_stack by not correctly pushing/popping from it. In cp_parser_lambda_expression we are calling (in order): push_deferring_access_checks (dk_no_deferred); cp_parser_start_tentative_firewall (parser); pop_deferring_access_checks (); cp_parser_end_tentative_firewall (parser, start, lambda_expr); But the order of the last two calls ought to be swapped. So this fixes it: diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 6ae45b0..33f09b8 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -9781,8 +9781,6 @@ cp_parser_lambda_expression (cp_parser* parser) = auto_is_implicit_function_template_parm_p; } - pop_deferring_access_checks (); - /* This field is only used during parsing of the lambda. */ LAMBDA_EXPR_THIS_CAPTURE (lambda_expr) = NULL_TREE; @@ -9798,6 +9796,8 @@ cp_parser_lambda_expression (cp_parser* parser) cp_parser_end_tentative_firewall (parser, start, lambda_expr); + pop_deferring_access_checks (); + return lambda_expr; }