[Lldb-commits] [lldb] [llvm] [DebugInfo][LLDB] Fix generic DW_OP_const handling (PR #204353)

via lldb-commits lldb-commits at lists.llvm.org
Wed Jun 24 19:14:21 PDT 2026


================
@@ -3251,10 +3252,39 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
                             &AP](const DbgValueLocEntry &Entry,
                                  DIExpressionCursor &Cursor) -> bool {
     if (Entry.isInt()) {
-      if (BT && (BT->getEncoding() == dwarf::DW_ATE_boolean))
+      if (BT && (BT->getEncoding() == dwarf::DW_ATE_boolean)) {
         DwarfExpr.addBooleanConstant(Entry.getInt());
-      else if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
-                      BT->getEncoding() == dwarf::DW_ATE_signed_char))
+        return true;
+      }
+
+      bool IsSigned = BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
+                             BT->getEncoding() == dwarf::DW_ATE_signed_char);
+      if (BT && AP.getDwarfVersion() >= 4 &&
+          !AP.getDwarfDebug()->tuneForSCE() && !Cursor) {
+        // DW_OP_const* pushes a generic, address-sized value. For a wider
+        // source integer value that cannot fit in the generic type, use
+        // DW_OP_implicit_value to preserve the source bytes instead. Keep this
+        // limited to complete constant values: SCE tuning already avoids
+        // DW_OP_implicit_value for compatibility, and expressions with
+        // remaining operations may need a scalar stack value rather than an
+        // implicit value block.
+        unsigned GenericBitSize = AP.MAI.getCodePointerSize() * 8;
+        uint64_t TypeBitSize = BT->getSizeInBits();
+        bool IsByteSized = TypeBitSize % 8 == 0;
+        bool IsOutOfRange =
+            IsSigned ? !isIntN(GenericBitSize, Entry.getInt())
+                     : !isUIntN(GenericBitSize,
+                                static_cast<uint64_t>(Entry.getInt()));
+        if (TypeBitSize > GenericBitSize && IsByteSized && IsOutOfRange) {
+          DwarfExpr.addImplicitValue(
+              APInt(static_cast<unsigned>(TypeBitSize),
+                    static_cast<uint64_t>(Entry.getInt()), IsSigned),
----------------
firmiana402 wrote:

In this context, `Entry.getInt()` is meant to be converted to `BT` (BaseType), whose corresponding type width is `TypeBitSize`, so it seems a bit surprising that the assertion fails here.

You mentioned: "If `64 > TypeBitSize > GenericBitSize` and `Entry.getInt()` has bits outside of `TypeBitSize`, `APInt` triggers an assertion as `ImplicitTrunc` is false by default."

One scenario I can imagine is the following: a variable of some basic type is assigned a constant that exceeds the representable range of its type. That could indeed lead to the assertion failure (in practice, the constant should just be wrapped around to fit within the representable range of the basic type). If this guess is correct, the assertion should be fixable simply by setting `ImplicitTrunc` to `true`.

That said, could you share more details about how the assertion is triggered — for example, a code example or reproducer? That would help me understand the issue.

https://github.com/llvm/llvm-project/pull/204353


More information about the lldb-commits mailing list