https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80267

--- Comment #3 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
(I'm using the testcase in Comment 1.) a() is a function template, so when we
instantiate it, we call tsubst_expr with args = int to all stuff in
BIND_EXPR_BODY of the function.  We'll end up calling tsubst_copy for VAR_DECL
'c' in the nested lambda.  lookup_name tries to find an instatiation of 'c',
but the one it finds has a different context ("auto &c = b;" vs "c;" from the
outer lambda), so we ignore that and do
  r = tsubst_decl (t, args, complain);
which created a new VAR_DECL, with DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P =
0.
The type of this decl is a reference, so
  if (decl_maybe_constant_var_p (r))
is true 
so we do
  tree init = tsubst_init (DECL_INITIAL (t), r, args,
                           complain, in_decl);
and
  init = maybe_constant_init (init);
so INIT is "*b".  It's not reduced_constant_expression_p so
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P is left unset.  Which means that
decl_constant_var_p (r) in the assert doesn't hold and we crash.

So there's a discrepancy in DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P for the
specializations of 'c'.  The original one has it (set in cp_finish_decl -- the
initializer "b" is potential_constant_expression), but the second one doesn't
have it ("*b" isn't reduced_constant_expression_p.

Reply via email to