This is needed to fix https://github.com/llvm/llvm-project/issues/60155.
An assertion in tryCaptureVariable fails because SubstDefaultArgument pushes the context for the lambda's function operator, but the LambdaScopeInfo isn't being pushed to the stack.
It appears that the assertion started to fail in 4409a83c293537e22da046b54e9f69454cdd3dca, which delays instantiation of default arguments. By the time the default arguments are instantiated, which happens after inherited::TransformLambdaExpr is called, the lambda scope has already been popped.
I'm struggling to understand the change. If I'm following correctly, it looks like we're trying to capture the variable used in the default argument. If so, that seems wrong; I think we shouldn't even be trying to capture a variable for such usage.
I jumped into a debugger to poke around a bit. Perhaps the right change is to detect the use in a default argument in the code below so that the call to getCapturedDeclRefType() can be skipped for a non-ODR use.
/localdisk2/thonerma/llvm-project/clang/lib/Sema/SemaExpr.cpp: 3265 ExprResult Sema::BuildDeclarationNameExpr( 3266 const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D, 3267 NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, 3268 bool AcceptInvalidDecl) { ..... 3326 switch (D->getKind()) { ..... 3389 case Decl::Var: 3390 case Decl::VarTemplateSpecialization: 3391 case Decl::VarTemplatePartialSpecialization: 3392 case Decl::Decomposition: 3393 case Decl::OMPCapturedExpr: 3394 // In C, "extern void blah;" is valid and is an r-value. 3395 if (!getLangOpts().CPlusPlus && !type.hasQualifiers() && 3396 type->isVoidType()) { 3397 valueKind = VK_PRValue; 3398 break; 3399 } 3400 [[fallthrough]]; 3401 3402 case Decl::ImplicitParam: 3403 case Decl::ParmVar: { 3404 // These are always l-values. 3405 valueKind = VK_LValue; 3406 type = type.getNonReferenceType(); 3407 3408 // FIXME: Does the addition of const really only apply in 3409 // potentially-evaluated contexts? Since the variable isn't actually 3410 // captured in an unevaluated context, it seems that the answer is no. 3411 if (!isUnevaluatedContext()) { 3412 QualType CapturedType = getCapturedDeclRefType(cast<VarDecl>(VD), Loc); 3413 if (!CapturedType.isNull()) 3414 type = CapturedType; 3415 } 3416 3417 break; 3418 } ..... 3516 }