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;
 }

Reply via email to