Skip to content

Commit 61671e2

Browse files
authored
[DebugInfo] Fix faulty DIExpression::appendToStack assert (#85255)
The appendToStack() function asserts that no DW_OP_stack_value or DW_OP_LLVM_fragment operations are present in the operations to be appended. The function did that by iterating over all elements in the array rather than just the operations, leading it to falsely asserting on the following input produced by getExt(), since 159 (0x9f) is the DWARF code for DW_OP_stack_value: {dwarf::DW_OP_LLVM_convert, 159, dwarf::DW_ATE_signed} Fix this by using expr_op iterators.
1 parent a7f3d17 commit 61671e2

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,11 +1880,12 @@ DIExpression *DIExpression::append(const DIExpression *Expr,
18801880
DIExpression *DIExpression::appendToStack(const DIExpression *Expr,
18811881
ArrayRef<uint64_t> Ops) {
18821882
assert(Expr && !Ops.empty() && "Can't append ops to this expression");
1883-
assert(none_of(Ops,
1884-
[](uint64_t Op) {
1885-
return Op == dwarf::DW_OP_stack_value ||
1886-
Op == dwarf::DW_OP_LLVM_fragment;
1887-
}) &&
1883+
assert(std::none_of(expr_op_iterator(Ops.begin()),
1884+
expr_op_iterator(Ops.end()),
1885+
[](auto Op) {
1886+
return Op.getOp() == dwarf::DW_OP_stack_value ||
1887+
Op.getOp() == dwarf::DW_OP_LLVM_fragment;
1888+
}) &&
18881889
"Can't append this op");
18891890

18901891
// Append a DW_OP_deref after Expr's current op list if it's non-empty and

llvm/unittests/IR/MetadataTest.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3560,6 +3560,27 @@ TEST_F(DIExpressionTest, foldConstant) {
35603560
#undef EXPECT_FOLD_CONST
35613561
}
35623562

3563+
TEST_F(DIExpressionTest, appendToStackAssert) {
3564+
DIExpression *Expr = DIExpression::get(Context, {});
3565+
3566+
// Verify that the DW_OP_LLVM_convert operands, which have the same values as
3567+
// DW_OP_stack_value and DW_OP_LLVM_fragment, do not get interpreted as such
3568+
// operations. This previously triggered an assert.
3569+
uint64_t FromSize = dwarf::DW_OP_stack_value;
3570+
uint64_t ToSize = dwarf::DW_OP_LLVM_fragment;
3571+
uint64_t Ops[] = {
3572+
dwarf::DW_OP_LLVM_convert, FromSize, dwarf::DW_ATE_signed,
3573+
dwarf::DW_OP_LLVM_convert, ToSize, dwarf::DW_ATE_signed,
3574+
};
3575+
Expr = DIExpression::appendToStack(Expr, Ops);
3576+
3577+
uint64_t Expected[] = {
3578+
dwarf::DW_OP_LLVM_convert, FromSize, dwarf::DW_ATE_signed,
3579+
dwarf::DW_OP_LLVM_convert, ToSize, dwarf::DW_ATE_signed,
3580+
dwarf::DW_OP_stack_value};
3581+
EXPECT_EQ(Expr->getElements(), ArrayRef<uint64_t>(Expected));
3582+
}
3583+
35633584
typedef MetadataTest DIObjCPropertyTest;
35643585

35653586
TEST_F(DIObjCPropertyTest, get) {

0 commit comments

Comments
 (0)