================
@@ -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
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to