Skip to content

Commit 3c28076

Browse files
authored
Allow 128-bit discriminants in DWARF variants (#125578)
If a variant part has a 128-bit discriminator, then DwarfUnit::constructTypeDIE will assert. This patch fixes the problem by allowing any size of integer to be used here. This is largely accomplished by moving part of DwarfUnit::addConstantValue to a new method. Fixes #119655
1 parent 837bf32 commit 3c28076

File tree

3 files changed

+49
-27
lines changed

3 files changed

+49
-27
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,42 @@ void DwarfUnit::addUInt(DIEValueList &Block, dwarf::Form Form,
232232
addUInt(Block, (dwarf::Attribute)0, Form, Integer);
233233
}
234234

235+
void DwarfUnit::addIntAsBlock(DIE &Die, dwarf::Attribute Attribute, const APInt &Val) {
236+
DIEBlock *Block = new (DIEValueAllocator) DIEBlock;
237+
238+
// Get the raw data form of the large APInt.
239+
const uint64_t *Ptr64 = Val.getRawData();
240+
241+
int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
242+
bool LittleEndian = Asm->getDataLayout().isLittleEndian();
243+
244+
// Output the constant to DWARF one byte at a time.
245+
for (int i = 0; i < NumBytes; i++) {
246+
uint8_t c;
247+
if (LittleEndian)
248+
c = Ptr64[i / 8] >> (8 * (i & 7));
249+
else
250+
c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
251+
addUInt(*Block, dwarf::DW_FORM_data1, c);
252+
}
253+
254+
addBlock(Die, Attribute, Block);
255+
}
256+
257+
void DwarfUnit::addInt(DIE &Die, dwarf::Attribute Attribute,
258+
const APInt &Val, bool Unsigned) {
259+
unsigned CIBitWidth = Val.getBitWidth();
260+
if (CIBitWidth <= 64) {
261+
if (Unsigned)
262+
addUInt(Die, Attribute, std::nullopt, Val.getZExtValue());
263+
else
264+
addSInt(Die, Attribute, std::nullopt, Val.getSExtValue());
265+
return;
266+
}
267+
268+
addIntAsBlock(Die, Attribute, Val);
269+
}
270+
235271
void DwarfUnit::addSInt(DIEValueList &Die, dwarf::Attribute Attribute,
236272
std::optional<dwarf::Form> Form, int64_t Integer) {
237273
if (!Form)
@@ -484,25 +520,7 @@ void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, bool Unsigned) {
484520
return;
485521
}
486522

487-
DIEBlock *Block = new (DIEValueAllocator) DIEBlock;
488-
489-
// Get the raw data form of the large APInt.
490-
const uint64_t *Ptr64 = Val.getRawData();
491-
492-
int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
493-
bool LittleEndian = Asm->getDataLayout().isLittleEndian();
494-
495-
// Output the constant to DWARF one byte at a time.
496-
for (int i = 0; i < NumBytes; i++) {
497-
uint8_t c;
498-
if (LittleEndian)
499-
c = Ptr64[i / 8] >> (8 * (i & 7));
500-
else
501-
c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
502-
addUInt(*Block, dwarf::DW_FORM_data1, c);
503-
}
504-
505-
addBlock(Die, dwarf::DW_AT_const_value, Block);
523+
addIntAsBlock(Die, dwarf::DW_AT_const_value, Val);
506524
}
507525

508526
void DwarfUnit::addLinkageName(DIE &Die, StringRef LinkageName) {
@@ -972,12 +990,8 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
972990
DIE &Variant = createAndAddDIE(dwarf::DW_TAG_variant, Buffer);
973991
if (const ConstantInt *CI =
974992
dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) {
975-
if (DD->isUnsignedDIType(Discriminator->getBaseType()))
976-
addUInt(Variant, dwarf::DW_AT_discr_value, std::nullopt,
977-
CI->getZExtValue());
978-
else
979-
addSInt(Variant, dwarf::DW_AT_discr_value, std::nullopt,
980-
CI->getSExtValue());
993+
addInt(Variant, dwarf::DW_AT_discr_value, CI->getValue(),
994+
DD->isUnsignedDIType(Discriminator->getBaseType()));
981995
}
982996
constructMemberDIE(Variant, DDTy);
983997
} else {

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ class DwarfUnit : public DIEUnit {
167167

168168
void addSInt(DIELoc &Die, std::optional<dwarf::Form> Form, int64_t Integer);
169169

170+
/// Add an integer attribute data and value; value may be any width.
171+
void addInt(DIE &Die, dwarf::Attribute Attribute, const APInt &Integer,
172+
bool Unsigned);
173+
170174
/// Add a string attribute data and value.
171175
///
172176
/// We always emit a reference to the string pool instead of immediate
@@ -334,6 +338,10 @@ class DwarfUnit : public DIEUnit {
334338
void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT);
335339

336340
private:
341+
/// A helper to add a wide integer constant to a DIE using a block
342+
/// form.
343+
void addIntAsBlock(DIE &Die, dwarf::Attribute Attribute, const APInt &Val);
344+
337345
void constructTypeDIE(DIE &Buffer, const DIBasicType *BTy);
338346
void constructTypeDIE(DIE &Buffer, const DIStringType *BTy);
339347
void constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy);

llvm/test/DebugInfo/Generic/discriminated-union.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
; CHECK: DW_AT_alignment
2323
; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
2424
; CHECK: DW_TAG_variant
25-
; CHECK: DW_AT_discr_value [DW_FORM_data1] (0x00)
25+
; CHECK: DW_AT_discr_value [DW_FORM_block1] (<0x10> 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 )
2626
; CHECK: DW_TAG_member
2727
; CHECK: DW_AT_type
2828
; CHECK: DW_AT_alignment
@@ -71,7 +71,7 @@ attributes #0 = { nounwind uwtable }
7171
!21 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned)
7272
!22 = !DIDerivedType(tag: DW_TAG_member, name: "__1", scope: !18, file: !7, baseType: !23, size: 64, align: 64)
7373
!23 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&u8", baseType: !21, size: 64, align: 64)
74-
!24 = !DIDerivedType(tag: DW_TAG_member, scope: !14, file: !7, baseType: !25, size: 128, align: 64, extraData: i64 0)
74+
!24 = !DIDerivedType(tag: DW_TAG_member, scope: !14, file: !7, baseType: !25, size: 128, align: 64, extraData: i128 18446744073709551616)
7575
!25 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nope", scope: !12, file: !7, size: 128, align: 64, elements: !4, identifier: "7ce1efff6b82281ab9ceb730566e7e20::Nope")
7676
!27 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned)
7777
!28 = !DIExpression()

0 commit comments

Comments
 (0)