Author: MrEven132
Date: 2026-08-24T15:38:07+08:00
New Revision: 498e994ca9337aa1e60cf1a33ca4c7c36481b08d

URL: 
https://github.com/llvm/llvm-project/commit/498e994ca9337aa1e60cf1a33ca4c7c36481b08d
DIFF: 
https://github.com/llvm/llvm-project/commit/498e994ca9337aa1e60cf1a33ca4c7c36481b08d.diff

LOG: [lldb] Keep DW_OP_call_frame_cfa address-sized (#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

Added: 
    

Modified: 
    lldb/source/Expression/DWARFExpression.cpp
    lldb/unittests/Expression/DWARFExpressionTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Expression/DWARFExpression.cpp 
b/lldb/source/Expression/DWARFExpression.cpp
index 91c47546eeac7..40c69c65853a8 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -2043,6 +2043,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 094cfaf790a9a..b59bddff0cd1e 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -1533,6 +1533,26 @@ TEST_F(DWARFExpressionMockProcessTest, 
DW_OP_fbreg_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