Skip to content

Commit fab9bba

Browse files
committed
Unit test demonstrating failed assertion when handling debuginfo
Should fail with "Assertion `!NodePtr->isKnownSentinel()' failed."
1 parent f7bbc40 commit fab9bba

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

Diff for: llvm/unittests/IR/BasicBlockDbgInfoTest.cpp

+99
Original file line numberDiff line numberDiff line change
@@ -1525,4 +1525,103 @@ TEST(BasicBlockDbgInfoTest, DbgMoveToEnd) {
15251525
EXPECT_FALSE(Ret->hasDbgRecords());
15261526
}
15271527

1528+
// This fails with an assert: "Assertion `!NodePtr->isKnownSentinel()' failed."
1529+
//
1530+
// Original C source:
1531+
//
1532+
// int foo(int fd) { return fd; }
1533+
// int (* arr[2])(int fd) = { foo };
1534+
// int bar(int id, int arg) {
1535+
// int ret = arr[id](arg);
1536+
// return ret;
1537+
// }
1538+
//
1539+
// Build command used: clang --target=armv7m-none-eabi -Oz -g -mcpu=cortex-m3 -mthumb -mabi=aapcs -c comm_reduce.c -emit-llvm
1540+
TEST(BasicBlockDbgInfoTest, DbgKnownSentinelCrash) {
1541+
LLVMContext C;
1542+
std::unique_ptr<Module> M = parseIR(C, R"---(
1543+
@arr = dso_local local_unnamed_addr global [2 x ptr] [ptr @foo, ptr null], align 4, !dbg !0
1544+
1545+
; Function Attrs: minsize mustprogress nofree norecurse nosync nounwind optsize willreturn memory(none)
1546+
define dso_local noundef i32 @foo(i32 noundef returned %fd) #0 !dbg !19 {
1547+
entry:
1548+
#dbg_value(i32 %fd, !21, !DIExpression(), !22)
1549+
ret i32 %fd, !dbg !23
1550+
}
1551+
1552+
; Function Attrs: minsize nounwind optsize
1553+
define dso_local i32 @bar(i32 noundef %id, i32 noundef %arg) local_unnamed_addr #1 !dbg !24 {
1554+
entry:
1555+
#dbg_value(i32 %id, !28, !DIExpression(), !31)
1556+
#dbg_value(i32 %arg, !29, !DIExpression(), !31)
1557+
%arrayidx = getelementptr inbounds [2 x ptr], ptr @arr, i32 0, i32 %id, !dbg !32
1558+
%0 = load ptr, ptr %arrayidx, align 4, !dbg !32, !tbaa !33
1559+
%call = tail call i32 %0(i32 noundef %arg) #2, !dbg !32
1560+
#dbg_value(i32 %call, !30, !DIExpression(), !31)
1561+
ret i32 %call, !dbg !37
1562+
}
1563+
1564+
attributes #0 = { minsize mustprogress nofree norecurse nosync nounwind optsize willreturn memory(none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+armv7-m,+hwdiv,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" }
1565+
attributes #1 = { minsize nounwind optsize "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+armv7-m,+hwdiv,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" }
1566+
attributes #2 = { minsize nounwind optsize }
1567+
1568+
!llvm.dbg.cu = !{!2}
1569+
!llvm.module.flags = !{!12, !13, !14, !15, !16, !17}
1570+
1571+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
1572+
!1 = distinct !DIGlobalVariable(name: "arr", scope: !2, file: !3, line: 3, type: !5, isLocal: false, isDefinition: true)
1573+
!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None)
1574+
!3 = !DIFile(filename: "t.c", directory: "/")
1575+
!4 = !{!0}
1576+
!5 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 64, elements: !10)
1577+
!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32)
1578+
!7 = !DISubroutineType(types: !8)
1579+
!8 = !{!9, !9}
1580+
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
1581+
!10 = !{!11}
1582+
!11 = !DISubrange(count: 2)
1583+
!12 = !{i32 7, !"Dwarf Version", i32 5}
1584+
!13 = !{i32 2, !"Debug Info Version", i32 3}
1585+
!14 = !{i32 1, !"wchar_size", i32 4}
1586+
!15 = !{i32 1, !"min_enum_size", i32 4}
1587+
!16 = !{i32 7, !"frame-pointer", i32 2}
1588+
!17 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
1589+
!19 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 1, type: !7, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !20)
1590+
!20 = !{!21}
1591+
!21 = !DILocalVariable(name: "fd", arg: 1, scope: !19, file: !3, line: 1, type: !9)
1592+
!22 = !DILocation(line: 0, scope: !19)
1593+
!23 = !DILocation(line: 1, column: 19, scope: !19)
1594+
!24 = distinct !DISubprogram(name: "bar", scope: !3, file: !3, line: 5, type: !25, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !27)
1595+
!25 = !DISubroutineType(types: !26)
1596+
!26 = !{!9, !9, !9}
1597+
!27 = !{!28, !29, !30}
1598+
!28 = !DILocalVariable(name: "id", arg: 1, scope: !24, file: !3, line: 5, type: !9)
1599+
!29 = !DILocalVariable(name: "arg", arg: 2, scope: !24, file: !3, line: 5, type: !9)
1600+
!30 = !DILocalVariable(name: "ret", scope: !24, file: !3, line: 6, type: !9)
1601+
!31 = !DILocation(line: 0, scope: !24)
1602+
!32 = !DILocation(line: 6, column: 12, scope: !24)
1603+
!33 = !{!34, !34, i64 0}
1604+
!34 = !{!"any pointer", !35, i64 0}
1605+
!35 = !{!"omnipotent char", !36, i64 0}
1606+
!36 = !{!"Simple C/C++ TBAA"}
1607+
!37 = !DILocation(line: 7, column: 2, scope: !24)
1608+
)---");
1609+
ASSERT_TRUE(M);
1610+
1611+
Function *F = M->getFunction("bar");
1612+
BasicBlock &BB = F->getEntryBlock();
1613+
1614+
// Find %call
1615+
auto I = std::prev(BB.end(), 2);
1616+
1617+
BasicBlock *NewBB = BasicBlock::Create(C, "NewBB", F);
1618+
BasicBlock *NewBB2 = BasicBlock::Create(C, "NewBB2", F);
1619+
1620+
NewBB->splice(NewBB->end(), &BB, std::next(I), BB.end());
1621+
NewBB2->splice(NewBB2->end(), &BB, I, BB.end());
1622+
1623+
llvm::dbgs() << "Didn't crash!\n";
1624+
ASSERT_TRUE(true);
1625+
}
1626+
15281627
} // End anonymous namespace.

0 commit comments

Comments
 (0)