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.