mirror of
https://github.com/RPCS3/llvm.git
synced 2025-05-13 08:56:04 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265984 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
09e9ded8a1
commit
77e5760b43
@ -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.
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
9
test/MC/ELF/undefined-directional.s
Normal file
9
test/MC/ELF/undefined-directional.s
Normal file
@ -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
|
||||
|
9
test/MC/MachO/undefined-directional.s
Normal file
9
test/MC/MachO/undefined-directional.s
Normal file
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user