https://github.com/MrEven132 created 
https://github.com/llvm/llvm-project/pull/216684

`DW_OP_call_frame_cfa` currently constructs a `Scalar` directly from
`lldb::addr_t`. Since `addr_t` is a 64-bit carrier, the result remains 64 bits
when evaluating an expression for a 32-bit target, and subsequent address
arithmetic does not wrap at the target address width.

Normalize the CFA with the evaluator's existing `to_generic` helper after it
is pushed. This preserves the existing frame lookup, error handling, and
`LoadAddress` value type while making the scalar use the target address width.

Add an i386 unit test that verifies both 32-bit address arithmetic and the
resulting `APSInt` bit width.

Fixes #210980

>From fd82479f5f90d92a09674af4bf36399f8aacde7b Mon Sep 17 00:00:00 2001
From: MrEven132 <[email protected]>
Date: Mon, 17 Aug 2026 18:20:27 +0800
Subject: [PATCH] [lldb] Keep DW_OP_call_frame_cfa address-sized

---
 lldb/source/Expression/DWARFExpression.cpp    |  2 ++
 .../Expression/DWARFExpressionTest.cpp        | 21 +++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/lldb/source/Expression/DWARFExpression.cpp 
b/lldb/source/Expression/DWARFExpression.cpp
index f4c4f519b09c7..8232d87d53b92 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -2026,6 +2026,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
     case DW_OP_call_frame_cfa:
       if (llvm::Error err = Evaluate_DW_OP_call_frame_cfa(eval_ctx))
         return err;
+      stack.back().GetScalar() =
+          to_generic(stack.back().GetScalar().ULongLong());
       break;
 
     case DW_OP_form_tls_address:
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp 
b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index c2752e16672f7..fe7853a041bfd 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -27,6 +27,7 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/ABI.h"
 #include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
 #include "lldb/Utility/RegisterValue.h"
 #include "lldb/Utility/StreamString.h"
 #include "llvm/ADT/StringExtras.h"
@@ -1375,6 +1376,26 @@ TEST_F(DWARFExpressionMockProcessTest, 
DW_OP_bregx_address_size) {
   EXPECT_EQ(result->GetScalar().GetAPSInt().getBitWidth(), 32u);
 }
 
+TEST_F(DWARFExpressionMockProcessTest, DW_OP_call_frame_cfa_address_size) {
+  TestContext ctx;
+  ASSERT_TRUE(CreateTestContext(&ctx, "i386-pc-linux"));
+  auto frame_sp = std::make_shared<StackFrame>(
+      ctx.thread_sp, /*frame_idx=*/0, /*concrete_frame_idx=*/0, /*cfa=*/0x2a,
+      /*cfa_is_valid=*/true, /*pc=*/0x1000, StackFrame::Kind::Regular,
+      /*artificial=*/false, /*behaves_like_zeroth_frame=*/true,
+      /*sc_ptr=*/nullptr);
+  ExecutionContext exe_ctx(frame_sp);
+
+  // Address arithmetic wraps at the target address size. In particular,
+  // 0xffffffff + 1 is zero on this 32-bit target.
+  auto result =
+      Evaluate({DW_OP_call_frame_cfa, DW_OP_const4u, 0xff, 0xff, 0xff, 0xff,
+                DW_OP_plus, DW_OP_lit1, DW_OP_plus, DW_OP_stack_value},
+               {}, {}, &exe_ctx);
+  ASSERT_THAT_EXPECTED(result, ExpectScalar(32, 0x2a, false));
+  EXPECT_EQ(result->GetScalar().GetAPSInt().getBitWidth(), 32u);
+}
+
 TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) {
   EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit0, DW_OP_deref}), llvm::Failed());
 

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to