summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp40
-rw-r--r--llvm/test/MC/AArch64/error-location.s3
-rw-r--r--llvm/test/MC/ARM/error-location.s3
-rw-r--r--llvm/test/MC/ELF/undefined-directional.s9
-rw-r--r--llvm/test/MC/MachO/undefined-directional.s9
5 files changed, 45 insertions, 19 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.
}
diff --git a/llvm/test/MC/AArch64/error-location.s b/llvm/test/MC/AArch64/error-location.s
index a30f7706de7..6bb75f8cb5f 100644
--- a/llvm/test/MC/AArch64/error-location.s
+++ b/llvm/test/MC/AArch64/error-location.s
@@ -41,9 +41,6 @@
// CHECK: <unknown>:0: error: Common symbol 'common' cannot be used in assignment expr
.set v3, common
-// CHECK: <unknown>:0: error: Undefined temporary symbol
- .word 5f
-
// CHECK: <unknown>:0: error: symbol 'undef' could not be evaluated in a subtraction expression
.set v2, a-undef
diff --git a/llvm/test/MC/ARM/error-location.s b/llvm/test/MC/ARM/error-location.s
index 2f70f294b57..58ec585a928 100644
--- a/llvm/test/MC/ARM/error-location.s
+++ b/llvm/test/MC/ARM/error-location.s
@@ -23,9 +23,6 @@
@ CHECK: <unknown>:0: error: Common symbol 'common' cannot be used in assignment expr
.set v3, common
-@ CHECK: <unknown>:0: error: Undefined temporary symbol
- .word 5f
-
@ CHECK: <unknown>:0: error: symbol 'undef' could not be evaluated in a subtraction expression
.set v2, a-undef
diff --git a/llvm/test/MC/ELF/undefined-directional.s b/llvm/test/MC/ELF/undefined-directional.s
new file mode 100644
index 00000000000..74449d4e4f6
--- /dev/null
+++ b/llvm/test/MC/ELF/undefined-directional.s
@@ -0,0 +1,9 @@
+// RUN: not llvm-mc -triple x86_64-linux-gnu -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s
+
+// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: directional label undefined
+ jmp 1b
+// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: directional label undefined
+ jmp 1f
+// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: directional label undefined
+ jmp 2f
+
diff --git a/llvm/test/MC/MachO/undefined-directional.s b/llvm/test/MC/MachO/undefined-directional.s
new file mode 100644
index 00000000000..8d75228f835
--- /dev/null
+++ b/llvm/test/MC/MachO/undefined-directional.s
@@ -0,0 +1,9 @@
+// RUN: not llvm-mc -triple x86_64-apple-macosx -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s
+
+// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: directional label undefined
+ jmp 1b
+// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: directional label undefined
+ jmp 1f
+// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: directional label undefined
+ jmp 2f
+
OpenPOWER on IntegriCloud