summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2016-04-11 19:50:46 +0000
committerTim Northover <tnorthover@apple.com>2016-04-11 19:50:46 +0000
commit6b3169bb97a121ea9fcddafea20222b94cc59c51 (patch)
tree8dea76fe3bc1cfcf53bd2d3888b78a118f8c91e2 /llvm/lib/MC
parent53207a99f9d6a93c12bf0114556a7f0dd7e87d1f (diff)
downloadbcm5719-llvm-6b3169bb97a121ea9fcddafea20222b94cc59c51.tar.gz
bcm5719-llvm-6b3169bb97a121ea9fcddafea20222b94cc59c51.zip
MCParser: diagnose missing directional labels more clearly.
Before, ELF at least managed a diagnostic but it was a completely untraceable "undefined symbol" error. MachO had a variety of even worse behaviours: crash, emit corrupt file, or an equally bad message. llvm-svn: 265984
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp40
1 files changed, 27 insertions, 13 deletions
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index c7763fe7d63..700461576cb 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -146,6 +146,9 @@ private:
/// \brief List of bodies of anonymous macros.
std::deque<MCAsmMacro> MacroLikeBodies;
+ /// \brief List of forward directional labels for diagnosis at the end.
+ SmallVector<std::pair<SMLoc, MCSymbol *>, 4> DirectionalLabels;
+
/// Boolean tracking whether macro substitution is enabled.
unsigned MacrosEnabledFlag : 1;
@@ -696,18 +699,28 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// Targets that don't do subsections via symbols may not want this, though,
// so conservatively exclude them. Only do this if we're finalizing, though,
// as otherwise we won't necessarilly have seen everything yet.
- if (!NoFinalize && MAI.hasSubsectionsViaSymbols()) {
- for (const auto &TableEntry : getContext().getSymbols()) {
- MCSymbol *Sym = TableEntry.getValue();
- // Variable symbols may not be marked as defined, so check those
- // explicitly. If we know it's a variable, we have a definition for
- // the purposes of this check.
- if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
- // FIXME: We would really like to refer back to where the symbol was
- // first referenced for a source location. We need to add something
- // to track that. Currently, we just point to the end of the file.
- return Error(getLexer().getLoc(), "assembler local symbol '" +
- Sym->getName() + "' not defined");
+ if (!NoFinalize) {
+ if (MAI.hasSubsectionsViaSymbols()) {
+ for (const auto &TableEntry : getContext().getSymbols()) {
+ MCSymbol *Sym = TableEntry.getValue();
+ // Variable symbols may not be marked as defined, so check those
+ // explicitly. If we know it's a variable, we have a definition for
+ // the purposes of this check.
+ if (Sym->isTemporary() && !Sym->isVariable() && !Sym->isDefined())
+ // FIXME: We would really like to refer back to where the symbol was
+ // first referenced for a source location. We need to add something
+ // to track that. Currently, we just point to the end of the file.
+ HadError |=
+ Error(getLexer().getLoc(), "assembler local symbol '" +
+ Sym->getName() + "' not defined");
+ }
+ }
+
+ // Temporary symbols like the ones for directional jumps don't go in the
+ // symbol table. They also need to be diagnosed in all (final) cases.
+ for (std::pair<SMLoc, MCSymbol *> &LocSym : DirectionalLabels) {
+ if (LocSym.second->isUndefined())
+ HadError |= Error(LocSym.first, "directional label undefined");
}
}
@@ -917,7 +930,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b");
Res = MCSymbolRefExpr::create(Sym, Variant, getContext());
if (IDVal == "b" && Sym->isUndefined())
- return Error(Loc, "invalid reference to undefined symbol");
+ return Error(Loc, "directional label undefined");
+ DirectionalLabels.push_back(std::make_pair(Loc, Sym));
EndLoc = Lexer.getTok().getEndLoc();
Lex(); // Eat identifier.
}
OpenPOWER on IntegriCloud