diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index c7763fe7d63..700461576cb 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -146,6 +146,9 @@ private: /// \brief List of bodies of anonymous macros. std::deque MacroLikeBodies; + /// \brief List of forward directional labels for diagnosis at the end. + SmallVector, 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 &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/test/MC/AArch64/error-location.s b/test/MC/AArch64/error-location.s index a30f7706de7..6bb75f8cb5f 100644 --- a/test/MC/AArch64/error-location.s +++ b/test/MC/AArch64/error-location.s @@ -41,9 +41,6 @@ // CHECK: :0: error: Common symbol 'common' cannot be used in assignment expr .set v3, common -// CHECK: :0: error: Undefined temporary symbol - .word 5f - // CHECK: :0: error: symbol 'undef' could not be evaluated in a subtraction expression .set v2, a-undef diff --git a/test/MC/ARM/error-location.s b/test/MC/ARM/error-location.s index 2f70f294b57..58ec585a928 100644 --- a/test/MC/ARM/error-location.s +++ b/test/MC/ARM/error-location.s @@ -23,9 +23,6 @@ @ CHECK: :0: error: Common symbol 'common' cannot be used in assignment expr .set v3, common -@ CHECK: :0: error: Undefined temporary symbol - .word 5f - @ CHECK: :0: error: symbol 'undef' could not be evaluated in a subtraction expression .set v2, a-undef diff --git a/test/MC/ELF/undefined-directional.s b/test/MC/ELF/undefined-directional.s new file mode 100644 index 00000000000..74449d4e4f6 --- /dev/null +++ b/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/test/MC/MachO/undefined-directional.s b/test/MC/MachO/undefined-directional.s new file mode 100644 index 00000000000..8d75228f835 --- /dev/null +++ b/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 +