[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