[clang] [Clang][CodeGen][Sema] Fix crash when compiling naked lambdas (PR #165524)
Eli Friedman via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 31 14:17:07 PDT 2025
================
@@ -1277,44 +1277,58 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
MD && !MD->isStatic()) {
bool IsInLambda =
MD->getParent()->isLambda() && MD->getOverloadedOperator() == OO_Call;
- if (MD->isImplicitObjectMemberFunction())
- CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
- if (IsInLambda) {
- // We're in a lambda; figure out the captures.
- MD->getParent()->getCaptureFields(LambdaCaptureFields,
- LambdaThisCaptureField);
- if (LambdaThisCaptureField) {
- // If the lambda captures the object referred to by '*this' - either by
- // value or by reference, make sure CXXThisValue points to the correct
- // object.
-
- // Get the lvalue for the field (which is a copy of the enclosing object
- // or contains the address of the enclosing object).
- LValue ThisFieldLValue = EmitLValueForLambdaField(LambdaThisCaptureField);
- if (!LambdaThisCaptureField->getType()->isPointerType()) {
- // If the enclosing object was captured by value, just use its
- // address. Sign this pointer.
- CXXThisValue = ThisFieldLValue.getPointer(*this);
- } else {
- // Load the lvalue pointed to by the field, since '*this' was captured
- // by reference.
- CXXThisValue =
- EmitLoadOfLValue(ThisFieldLValue, SourceLocation()).getScalarVal();
+
+ const FunctionDecl *FD = dyn_cast_if_present<FunctionDecl>(D);
+ bool IsNaked = FD && FD->hasAttr<NakedAttr>();
+ if (!IsNaked) {
+ if (MD->isImplicitObjectMemberFunction())
+ CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
+
+ if (IsInLambda) {
+ // We're in a lambda; figure out the captures.
+ MD->getParent()->getCaptureFields(LambdaCaptureFields,
+ LambdaThisCaptureField);
+ if (LambdaThisCaptureField) {
+ // If the lambda captures the object referred to by '*this' - either
+ // by value or by reference, make sure CXXThisValue points to the
+ // correct object.
+
+ // Get the lvalue for the field (which is a copy of the enclosing
+ // object or contains the address of the enclosing object).
+ LValue ThisFieldLValue =
+ EmitLValueForLambdaField(LambdaThisCaptureField);
+ if (!LambdaThisCaptureField->getType()->isPointerType()) {
+ // If the enclosing object was captured by value, just use its
+ // address. Sign this pointer.
+ CXXThisValue = ThisFieldLValue.getPointer(*this);
+ } else {
+ // Load the lvalue pointed to by the field, since '*this' was
+ // captured by reference.
+ CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation())
+ .getScalarVal();
+ }
}
- }
- for (auto *FD : MD->getParent()->fields()) {
- if (FD->hasCapturedVLAType()) {
- auto *ExprArg = EmitLoadOfLValue(EmitLValueForLambdaField(FD),
- SourceLocation()).getScalarVal();
- auto VAT = FD->getCapturedVLAType();
- VLASizeMap[VAT->getSizeExpr()] = ExprArg;
+
+ for (auto *FD : MD->getParent()->fields()) {
+ if (FD->hasCapturedVLAType()) {
+ auto *ExprArg =
+ EmitLoadOfLValue(EmitLValueForLambdaField(FD), SourceLocation())
+ .getScalarVal();
+ auto VAT = FD->getCapturedVLAType();
+ VLASizeMap[VAT->getSizeExpr()] = ExprArg;
+ }
}
+ } else if (MD->isImplicitObjectMemberFunction()) {
+ // Not in a lambda; just use 'this' from the method.
+ // FIXME: Should we generate a new load for each use of 'this'? The
+ // fast register allocator would be happier...
+ CXXThisValue = CXXABIThisValue;
}
- } else if (MD->isImplicitObjectMemberFunction()) {
- // Not in a lambda; just use 'this' from the method.
- // FIXME: Should we generate a new load for each use of 'this'? The
- // fast register allocator would be happier...
- CXXThisValue = CXXABIThisValue;
+ } else if (IsInLambda && MD->isImplicitObjectMemberFunction()) {
+ // Populate capture fields metadata for analysis. We skip
+ // EmitInstanceProlog to avoid emitting prologue code.
+ MD->getParent()->getCaptureFields(LambdaCaptureFields,
----------------
efriedma-quic wrote:
Can we refactor the code so it doesn't have two separate calls to getCaptureFields()?
https://github.com/llvm/llvm-project/pull/165524
More information about the cfe-commits
mailing list