diff options
| author | Eli Friedman <efriedma@codeaurora.org> | 2017-10-12 20:54:08 +0000 |
|---|---|---|
| committer | Eli Friedman <efriedma@codeaurora.org> | 2017-10-12 20:54:08 +0000 |
| commit | 48e7549691d7dbe3be1a78f7419953fb48181678 (patch) | |
| tree | ebd74766f7dcff1d508afefb13d25d788ef87e09 /llvm/lib/CodeGen | |
| parent | 993d2e67d85a9c137edeeb295ce56d81563b14a7 (diff) | |
| download | bcm5719-llvm-48e7549691d7dbe3be1a78f7419953fb48181678.tar.gz bcm5719-llvm-48e7549691d7dbe3be1a78f7419953fb48181678.zip | |
[DWARF] Fix bad comparator in sortGlobalExprs.
The comparator passed to std::sort must provide a strict weak ordering;
otherwise, the behavior is undefined.
Fixes an assertion failure generating debug info for globals
split by GlobalOpt. I have a testcase, but not sure how to reduce it,
so not included here. (Someone else came up with a testcase, but I
can't reproduce the crash with it, presumably because my version of LLVM
ends up sorting the array differently.)
This isn't really a complete fix (see the FIXME in the patch), but at
least it doesn't have undefined behavior.
Differential Revision: https://reviews.llvm.org/D38830
llvm-svn: 315619
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 048a284ade5..96761916127 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -543,13 +543,18 @@ static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> & sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) { std::sort(GVEs.begin(), GVEs.end(), [](DwarfCompileUnit::GlobalExpr A, DwarfCompileUnit::GlobalExpr B) { - if (A.Expr != B.Expr && A.Expr && B.Expr) { - auto FragmentA = A.Expr->getFragmentInfo(); - auto FragmentB = B.Expr->getFragmentInfo(); - if (FragmentA && FragmentB) - return FragmentA->OffsetInBits < FragmentB->OffsetInBits; - } - return false; + // Sort order: first null exprs, then exprs without fragment + // info, then sort by fragment offset in bits. + // FIXME: Come up with a more comprehensive comparator so + // the sorting isn't non-deterministic, and so the following + // std::unique call works correctly. + if (!A.Expr || !B.Expr) + return !!B.Expr; + auto FragmentA = A.Expr->getFragmentInfo(); + auto FragmentB = B.Expr->getFragmentInfo(); + if (!FragmentA || !FragmentB) + return !!FragmentB; + return FragmentA->OffsetInBits < FragmentB->OffsetInBits; }); GVEs.erase(std::unique(GVEs.begin(), GVEs.end(), [](DwarfCompileUnit::GlobalExpr A, |

