diff options
author | Adrian Prantl <aprantl@apple.com> | 2018-02-06 22:17:45 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2018-02-06 22:17:45 +0000 |
commit | c929f7ad423e9566dc9a06815d0f3f7f3d809db8 (patch) | |
tree | 705d15b04e8d0bf202bc035d8c981fa4eb0d6e56 /llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | |
parent | 0ccef9ee1693f774a9dc23a10e0d3d7bf8b9bfbf (diff) | |
download | bcm5719-llvm-c929f7ad423e9566dc9a06815d0f3f7f3d809db8.tar.gz bcm5719-llvm-c929f7ad423e9566dc9a06815d0f3f7f3d809db8.zip |
Fix a crash when emitting DIEs for variable-length arrays
VLAs may refer to a previous DIE to express the DW_AT_count of their
type. Clang generates an artificial "vla_expr" variable for this. If
this DIE hasn't been created yet LLVM asserts. This patch fixes this
by sorting the local variables so that dependencies come before they
are needed. It also replaces the linear scan in DWARFFile with a
std::map, which can be faster.
Differential Revision: https://reviews.llvm.org/D42940
llvm-svn: 324412
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 3cde5ad38ce..85a63248a21 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -568,13 +568,41 @@ DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, return Var; } +/// Determine whether a variable appears in a count: expression. +static bool dependsOn(DbgVariable *A, DbgVariable *B) { + auto *Array = dyn_cast<DICompositeType>(A->getType()); + if (!Array || Array->getTag() != dwarf::DW_TAG_array_type) + return false; + return llvm::any_of(Array->getElements(), [&](DINode *El) { + if (auto *Subrange = dyn_cast<DISubrange>(El)) { + auto Count = Subrange->getCount(); + if (auto *Var = Count.dyn_cast<DIVariable *>()) + return Var == B->getVariable(); + } + return false; + }); +} + +/// Sort local variables so that variables appearing inside of helper +/// expressions come first. +static bool sortLocalVars(DbgVariable *A, DbgVariable *B) { + return dependsOn(B, A); +} + DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope, SmallVectorImpl<DIE *> &Children, bool *HasNonScopeChildren) { assert(Children.empty()); DIE *ObjectPointer = nullptr; - for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope)) + // Emit function arguments (order is significant). + auto Vars = DU->getScopeVariables().lookup(Scope); + for (auto &DV : Vars.Args) + Children.push_back(constructVariableDIE(*DV.second, *Scope, ObjectPointer)); + + // Emit local variables. + std::stable_sort(Vars.Locals.begin(), Vars.Locals.end(), sortLocalVars); + for (DbgVariable *DV : Vars.Locals) Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer)); // Skip imported directives in gmlt-like data. |