[clang] [Clang][CodeGen] Fix crash when compiling naked lambdas (PR #165524)
Oliver Hunt via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 29 03:54:35 PDT 2025
================
@@ -1271,50 +1272,59 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
}
}
- EmitFunctionProlog(*CurFnInfo, CurFn, Args);
+ EmitFunctionProlog(*CurFnInfo, CurFn, Args);
if (const CXXMethodDecl *MD = dyn_cast_if_present<CXXMethodDecl>(D);
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();
+ }
}
----------------
ojhunt wrote:
I believe that this is incorrect - it appears to skip handling captures. Your test cases need to cover capturing variables, including capturing this.
https://github.com/llvm/llvm-project/pull/165524
More information about the cfe-commits
mailing list