diff options
author | Adrian Prantl <aprantl@apple.com> | 2018-04-27 22:05:31 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2018-04-27 22:05:31 +0000 |
commit | 4b542c6e64a07577d3cf445065cee75fa2221935 (patch) | |
tree | 54fb712fbeecea0227e10c4c4e2cfd273bcaecd7 /llvm/lib/CodeGen/AsmPrinter | |
parent | befce13328be3c0a4762adf26b0dd6a54e5592f5 (diff) | |
download | bcm5719-llvm-4b542c6e64a07577d3cf445065cee75fa2221935.tar.gz bcm5719-llvm-4b542c6e64a07577d3cf445065cee75fa2221935.zip |
Fix a bug that prevents global variables from having a DW_OP_deref.
For local variables the first DW_OP_deref is consumed by turning the
location kind into a memeory location, but that only makes sense for
values that are in a register to begin with, which cannot happen for
global variables that are attached to a symbol.
rdar://problem/39741860
This reapplies r330970 after fixing an uncovered bug in r331086 and
working around the situation caused by it.
llvm-svn: 331090
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h | 2 |
3 files changed, 10 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 2eb0157f1e0..4a5c7b324d6 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -230,8 +230,13 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( addOpAddress(*Loc, Sym); } } - if (Expr) - DwarfExpr->addExpression(Expr); + // Global variables attached to symbols are memory locations. + // It would be better if this were unconditional, but malformed input that + // mixes non-fragments and fragments for the same variable is too expensive + // to detect in the verifier. + if (!DwarfExpr->isMemoryLocation()) + DwarfExpr->setMemoryLocationKind(); + DwarfExpr->addExpression(Expr); } if (Loc) addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize()); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index 379e9b14569..043d02e3ce4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -361,7 +361,7 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor, break; case dwarf::DW_OP_deref: assert(LocationKind != Register); - if (LocationKind != Memory && isMemoryLocation(ExprCursor)) + if (LocationKind != Memory && ::isMemoryLocation(ExprCursor)) // Turning this into a memory location description makes the deref // implicit. LocationKind = Memory; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h index ea5cbc40ba3..7d6d45e64d6 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -211,6 +211,8 @@ public: /// Emit an unsigned constant. void addUnsignedConstant(const APInt &Value); + bool isMemoryLocation() const { return LocationKind == Memory; } + /// Lock this down to become a memory location description. void setMemoryLocationKind() { assert(LocationKind == Unknown); |