[PATCH] D143109: [Sema] Push a LambdaScopeInfo before calling SubstDefaultArgument
Tom Honermann via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 15 13:31:51 PST 2023
tahonermann requested changes to this revision.
tahonermann added inline comments.
This revision now requires changes to proceed.
================
Comment at: clang/lib/Sema/SemaExpr.cpp:19085-19092
+ // If the variable is used in a default argument expression of a lambda call
+ // operator, switch to the enclosing context to sync up with the function
+ // scope.
+ if (isLambdaCallOperator(DC))
+ if (auto *PVD = dyn_cast_or_null<ParmVarDecl>(
+ ExprEvalContexts.back().ManglingContextDecl))
+ if (PVD->getDeclContext() == DC)
----------------
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 }
================
Comment at: clang/test/SemaCXX/lambda-default-arg.cpp:6
+ return [=](float b = a) -> bool {
+ return a < 0;
+ }();
----------------
Is the use of `a` in the lambda body intentional? It isn't needed to reproduce the assertion failure, so its presence here is a bit confusing from a test perspective as it implies that variable capture is somehow related. I suggest just returning `true`. Likewise for the other two tests.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D143109/new/
https://reviews.llvm.org/D143109
More information about the cfe-commits
mailing list