Index: include/llvm/MC/MCWinCOFFStreamer.h =================================================================== --- include/llvm/MC/MCWinCOFFStreamer.h +++ include/llvm/MC/MCWinCOFFStreamer.h @@ -73,7 +73,7 @@ void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override; private: - LLVM_ATTRIBUTE_NORETURN void FatalError(const Twine &Msg) const; + void Error(const Twine &Msg) const; }; } Index: lib/MC/ELFObjectWriter.cpp =================================================================== --- lib/MC/ELFObjectWriter.cpp +++ lib/MC/ELFObjectWriter.cpp @@ -630,28 +630,36 @@ // In general, ELF has no relocations for -B. It can only represent (A + C) // or (A + C - R). If B = R + K and the relocation is not pcrel, we can // replace B to implement it: (A - R - K + C) - if (IsPCRel) - Asm.getContext().reportFatalError( + if (IsPCRel) { + Asm.getContext().reportError( Fixup.getLoc(), "No relocation available to represent this relative expression"); + return; + } const auto &SymB = cast(RefB->getSymbol()); - if (SymB.isUndefined()) - Asm.getContext().reportFatalError( + if (SymB.isUndefined()) { + Asm.getContext().reportError( Fixup.getLoc(), Twine("symbol '") + SymB.getName() + "' can not be undefined in a subtraction expression"); + return; + } assert(!SymB.isAbsolute() && "Should have been folded"); const MCSection &SecB = SymB.getSection(); - if (&SecB != &FixupSection) - Asm.getContext().reportFatalError( + if (&SecB != &FixupSection) { + Asm.getContext().reportError( Fixup.getLoc(), "Cannot represent a difference across sections"); + return; + } - if (::isWeak(SymB)) - Asm.getContext().reportFatalError( + if (::isWeak(SymB)) { + Asm.getContext().reportError( Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol"); + return; + } uint64_t SymBOffset = Layout.getSymbolOffset(SymB); uint64_t K = SymBOffset - FixupOffset; @@ -784,8 +792,10 @@ Renames.count(&Symbol))) continue; - if (Symbol.isTemporary() && Symbol.isUndefined()) - Ctx.reportFatalError(SMLoc(), "Undefined temporary"); + if (Symbol.isTemporary() && Symbol.isUndefined()) { + Ctx.reportError(SMLoc(), "Undefined temporary symbol"); + continue; + } ELFSymbolData MSD; MSD.Symbol = cast(&Symbol); Index: lib/MC/MCAssembler.cpp =================================================================== --- lib/MC/MCAssembler.cpp +++ lib/MC/MCAssembler.cpp @@ -179,14 +179,19 @@ const MCExpr *Expr = Symbol.getVariableValue(); MCValue Value; - if (!Expr->evaluateAsValue(Value, *this)) - llvm_unreachable("Invalid Expression"); + if (!Expr->evaluateAsValue(Value, *this)) { + Assembler.getContext().reportError( + SMLoc(), "expression could not be evaluated"); + return nullptr; + } const MCSymbolRefExpr *RefB = Value.getSymB(); - if (RefB) - Assembler.getContext().reportFatalError( + if (RefB) { + Assembler.getContext().reportError( SMLoc(), Twine("symbol '") + RefB->getSymbol().getName() + "' could not be evaluated in a subtraction expression"); + return nullptr; + } const MCSymbolRefExpr *A = Value.getSymA(); if (!A) @@ -196,9 +201,10 @@ const MCAssembler &Asm = getAssembler(); if (ASym.isCommon()) { // FIXME: we should probably add a SMLoc to MCExpr. - Asm.getContext().reportFatalError(SMLoc(), - "Common symbol " + ASym.getName() + - " cannot be used in assignment expr"); + Asm.getContext().reportError(SMLoc(), + "Common symbol '" + ASym.getName() + + "' cannot be used in assignment expr"); + return nullptr; } return &ASym; @@ -436,8 +442,13 @@ // probably merge the two into a single callback that tries to evaluate a // fixup and records a relocation if one is needed. const MCExpr *Expr = Fixup.getValue(); - if (!Expr->evaluateAsRelocatable(Target, &Layout, &Fixup)) - getContext().reportFatalError(Fixup.getLoc(), "expected relocatable expression"); + if (!Expr->evaluateAsRelocatable(Target, &Layout, &Fixup)) { + getContext().reportError(Fixup.getLoc(), "expected relocatable expression"); + // Claim to have completely evaluated the fixup, to prevent any further + // processing from being done. + Value = 0; + return true; + } bool IsPCRel = Backend.getFixupKindInfo( Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; Index: lib/MC/WinCOFFObjectWriter.cpp =================================================================== --- lib/MC/WinCOFFObjectWriter.cpp +++ lib/MC/WinCOFFObjectWriter.cpp @@ -706,14 +706,17 @@ const MCSymbol &Symbol = Target.getSymA()->getSymbol(); const MCSymbol &A = Symbol; - if (!A.isRegistered()) - Asm.getContext().reportFatalError(Fixup.getLoc(), + if (!A.isRegistered()) { + Asm.getContext().reportError(Fixup.getLoc(), Twine("symbol '") + A.getName() + "' can not be undefined"); + return; + } if (A.isTemporary() && A.isUndefined()) { - Asm.getContext().reportFatalError(Fixup.getLoc(), + Asm.getContext().reportError(Fixup.getLoc(), Twine("assembler label '") + A.getName() + "' can not be undefined"); + return; } MCSection *Section = Fragment->getParent(); @@ -731,17 +734,21 @@ if (SymB) { const MCSymbol *B = &SymB->getSymbol(); - if (!B->getFragment()) - Asm.getContext().reportFatalError( + if (!B->getFragment()) { + Asm.getContext().reportError( Fixup.getLoc(), Twine("symbol '") + B->getName() + "' can not be undefined in a subtraction expression"); + return; + } - if (!A.getFragment()) - Asm.getContext().reportFatalError( + if (!A.getFragment()) { + Asm.getContext().reportError( Fixup.getLoc(), Twine("symbol '") + Symbol.getName() + "' can not be undefined in a subtraction expression"); + return; + } CrossSection = &Symbol.getSection() != &B->getSection(); Index: lib/MC/WinCOFFStreamer.cpp =================================================================== --- lib/MC/WinCOFFStreamer.cpp +++ lib/MC/WinCOFFStreamer.cpp @@ -122,29 +122,37 @@ "Got non-COFF section in the COFF backend!"); if (CurSymbol) - FatalError("starting a new symbol definition without completing the " - "previous one"); + Error("starting a new symbol definition without completing the " + "previous one"); CurSymbol = Symbol; } void MCWinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { - if (!CurSymbol) - FatalError("storage class specified outside of symbol definition"); + if (!CurSymbol) { + Error("storage class specified outside of symbol definition"); + return; + } - if (StorageClass & ~COFF::SSC_Invalid) - FatalError("storage class value '" + Twine(StorageClass) + + if (StorageClass & ~COFF::SSC_Invalid) { + Error("storage class value '" + Twine(StorageClass) + "' out of range"); + return; + } getAssembler().registerSymbol(*CurSymbol); cast(CurSymbol)->setClass((uint16_t)StorageClass); } void MCWinCOFFStreamer::EmitCOFFSymbolType(int Type) { - if (!CurSymbol) - FatalError("symbol type specified outside of a symbol definition"); + if (!CurSymbol) { + Error("symbol type specified outside of a symbol definition"); + return; + } - if (Type & ~0xffff) - FatalError("type value '" + Twine(Type) + "' out of range"); + if (Type & ~0xffff) { + Error("type value '" + Twine(Type) + "' out of range"); + return; + } getAssembler().registerSymbol(*CurSymbol); cast(CurSymbol)->setType((uint16_t)Type); @@ -152,7 +160,7 @@ void MCWinCOFFStreamer::EndCOFFSymbolDef() { if (!CurSymbol) - FatalError("ending symbol definition without starting one"); + Error("ending symbol definition without starting one"); CurSymbol = nullptr; } @@ -281,9 +289,8 @@ MCObjectStreamer::FinishImpl(); } -LLVM_ATTRIBUTE_NORETURN -void MCWinCOFFStreamer::FatalError(const Twine &Msg) const { - getContext().reportFatalError(SMLoc(), Msg); +void MCWinCOFFStreamer::Error(const Twine &Msg) const { + getContext().reportError(SMLoc(), Msg); } } Index: lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp @@ -90,9 +90,11 @@ Log2Size = llvm::Log2_32(4); // This encompasses the relocation for the whole 21-bit value. switch (Sym->getKind()) { - default: - Asm.getContext().reportFatalError(Fixup.getLoc(), - "ADR/ADRP relocations must be GOT relative"); + default: { + Asm.getContext().reportError(Fixup.getLoc(), + "ADR/ADRP relocations must be GOT relative"); + return false; + } case MCSymbolRefExpr::VK_PAGE: RelocType = unsigned(MachO::ARM64_RELOC_PAGE21); return true; @@ -170,25 +172,25 @@ // assembler local symbols. If we got here, that's not what we have, // so complain loudly. if (Kind == AArch64::fixup_aarch64_pcrel_branch19) { - Asm.getContext().reportFatalError(Fixup.getLoc(), - "conditional branch requires assembler-local" - " label. '" + - Target.getSymA()->getSymbol().getName() + - "' is external."); + Asm.getContext().reportError(Fixup.getLoc(), + "conditional branch requires assembler-local" + " label. '" + + Target.getSymA()->getSymbol().getName() + + "' is external."); return; } // 14-bit branch relocations should only target internal labels, and so // should never get here. if (Kind == AArch64::fixup_aarch64_pcrel_branch14) { - Asm.getContext().reportFatalError(Fixup.getLoc(), - "Invalid relocation on conditional branch!"); + Asm.getContext().reportError(Fixup.getLoc(), + "Invalid relocation on conditional branch!"); return; } if (!getAArch64FixupKindMachOInfo(Fixup, Type, Target.getSymA(), Log2Size, - Asm)) { - Asm.getContext().reportFatalError(Fixup.getLoc(), "unknown AArch64 fixup kind!"); + Asm)) { + Asm.getContext().reportError(Fixup.getLoc(), "unknown AArch64 fixup kind!"); return; } @@ -200,8 +202,9 @@ Type = MachO::ARM64_RELOC_UNSIGNED; if (IsPCRel) { - Asm.getContext().reportFatalError(Fixup.getLoc(), - "PC relative absolute relocation!"); + Asm.getContext().reportError(Fixup.getLoc(), + "PC relative absolute relocation!"); + return; // FIXME: x86_64 sets the type to a branch reloc here. Should we do // something similar? @@ -229,16 +232,20 @@ Writer->addRelocation(A_Base, Fragment->getParent(), MRE); return; } else if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None || - Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None) + Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None) { // Otherwise, neither symbol can be modified. - Asm.getContext().reportFatalError(Fixup.getLoc(), - "unsupported relocation of modified symbol"); + Asm.getContext().reportError(Fixup.getLoc(), + "unsupported relocation of modified symbol"); + return; + } // We don't support PCrel relocations of differences. - if (IsPCRel) - Asm.getContext().reportFatalError(Fixup.getLoc(), - "unsupported pc-relative relocation of " - "difference"); + if (IsPCRel) { + Asm.getContext().reportError(Fixup.getLoc(), + "unsupported pc-relative relocation of " + "difference"); + return; + } // AArch64 always uses external relocations. If there is no symbol to use as // a base address (a local symbol with no preceding non-local symbol), @@ -246,20 +253,26 @@ // // FIXME: We should probably just synthesize an external symbol and use // that. - if (!A_Base) - Asm.getContext().reportFatalError( + if (!A_Base) { + Asm.getContext().reportError( Fixup.getLoc(), "unsupported relocation of local symbol '" + A->getName() + "'. Must have non-local symbol earlier in section."); - if (!B_Base) - Asm.getContext().reportFatalError( + return; + } + if (!B_Base) { + Asm.getContext().reportError( Fixup.getLoc(), "unsupported relocation of local symbol '" + B->getName() + "'. Must have non-local symbol earlier in section."); + return; + } - if (A_Base == B_Base && A_Base) - Asm.getContext().reportFatalError(Fixup.getLoc(), - "unsupported relocation with identical base"); + if (A_Base == B_Base && A_Base) { + Asm.getContext().reportError( + Fixup.getLoc(), "unsupported relocation with identical base"); + return; + } Value += (!A->getFragment() ? 0 : Writer->getSymbolAddress(*A, Layout)) - (!A_Base || !A_Base->getFragment() ? 0 : Writer->getSymbolAddress( @@ -309,10 +322,12 @@ // we need to preserve and merge with the new Target? How about // the FixedValue? if (!Symbol->getVariableValue()->evaluateAsRelocatable(Target, &Layout, - &Fixup)) - Asm.getContext().reportFatalError(Fixup.getLoc(), - "unable to resolve variable '" + - Symbol->getName() + "'"); + &Fixup)) { + Asm.getContext().reportError(Fixup.getLoc(), + "unable to resolve variable '" + + Symbol->getName() + "'"); + return; + } return recordRelocation(Writer, Asm, Layout, Fragment, Fixup, Target, FixedValue); } @@ -337,11 +352,13 @@ Value += Layout.getSymbolOffset(*Symbol) - Layout.getSymbolOffset(*Base); } else if (Symbol->isInSection()) { - if (!CanUseLocalRelocation) - Asm.getContext().reportFatalError( + if (!CanUseLocalRelocation) { + Asm.getContext().reportError( Fixup.getLoc(), "unsupported relocation of local symbol '" + Symbol->getName() + "'. Must have non-local symbol earlier in section."); + return; + } // Adjust the relocation to be section-relative. // The index is the section ordinal (1-based). const MCSection &Sec = Symbol->getSection(); @@ -361,9 +378,10 @@ return; } } - Asm.getContext().reportFatalError(Fixup.getLoc(), + Asm.getContext().reportError(Fixup.getLoc(), "unsupported relocation of variable '" + Symbol->getName() + "'"); + return; } } Index: lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -395,8 +395,10 @@ Value = -Value; isAdd = false; } - if (Ctx && Value >= 4096) - Ctx->reportFatalError(Fixup.getLoc(), "out of range pc-relative fixup value"); + if (Ctx && Value >= 4096) { + Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value"); + return 0; + } Value |= isAdd << 23; // Same addressing mode as fixup_arm_pcrel_10, @@ -414,8 +416,10 @@ Value = -Value; opc = 2; // 0b0010 } - if (Ctx && ARM_AM::getSOImmVal(Value) == -1) - Ctx->reportFatalError(Fixup.getLoc(), "out of range pc-relative fixup value"); + if (Ctx && ARM_AM::getSOImmVal(Value) == -1) { + Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value"); + return 0; + } // Encode the immediate and shift the opcode into place. return ARM_AM::getSOImmVal(Value) | (opc << 21); } @@ -544,8 +548,10 @@ // could have an error on our hands. if (Ctx && !STI->getFeatureBits()[ARM::FeatureThumb2] && IsResolved) { const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value); - if (FixupDiagnostic) - Ctx->reportFatalError(Fixup.getLoc(), FixupDiagnostic); + if (FixupDiagnostic) { + Ctx->reportError(Fixup.getLoc(), FixupDiagnostic); + return 0; + } } // Offset by 4, and don't encode the low two bits. return ((Value - 4) >> 2) & 0xff; @@ -559,16 +565,20 @@ // Offset by 4 and don't encode the lower bit, which is always 0. if (Ctx && !STI->getFeatureBits()[ARM::FeatureThumb2]) { const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value); - if (FixupDiagnostic) - Ctx->reportFatalError(Fixup.getLoc(), FixupDiagnostic); + if (FixupDiagnostic) { + Ctx->reportError(Fixup.getLoc(), FixupDiagnostic); + return 0; + } } return ((Value - 4) >> 1) & 0x7ff; case ARM::fixup_arm_thumb_bcc: // Offset by 4 and don't encode the lower bit, which is always 0. if (Ctx && !STI->getFeatureBits()[ARM::FeatureThumb2]) { const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value); - if (FixupDiagnostic) - Ctx->reportFatalError(Fixup.getLoc(), FixupDiagnostic); + if (FixupDiagnostic) { + Ctx->reportError(Fixup.getLoc(), FixupDiagnostic); + return 0; + } } return ((Value - 4) >> 1) & 0xff; case ARM::fixup_arm_pcrel_10_unscaled: { @@ -580,8 +590,10 @@ isAdd = false; } // The value has the low 4 bits encoded in [3:0] and the high 4 in [11:8]. - if (Ctx && Value >= 256) - Ctx->reportFatalError(Fixup.getLoc(), "out of range pc-relative fixup value"); + if (Ctx && Value >= 256) { + Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value"); + return 0; + } Value = (Value & 0xf) | ((Value & 0xf0) << 4); return Value | (isAdd << 23); } @@ -599,8 +611,10 @@ } // These values don't encode the low two bits since they're always zero. Value >>= 2; - if (Ctx && Value >= 256) - Ctx->reportFatalError(Fixup.getLoc(), "out of range pc-relative fixup value"); + if (Ctx && Value >= 256) { + Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value"); + return 0; + } Value |= isAdd << 23; // Same addressing mode as fixup_arm_pcrel_10, but with 16-bit halfwords Index: lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -509,8 +509,10 @@ /// necessary. void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override { if (const MCSymbolRefExpr *SRE = dyn_cast_or_null(Value)) - if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) - getContext().reportFatalError(Loc, "relocated expression must be 32-bit"); + if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) { + getContext().reportError(Loc, "relocated expression must be 32-bit"); + return; + } EmitDataMappingSymbol(); MCELFStreamer::EmitValueImpl(Value, Size, Loc); Index: lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp +++ lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp @@ -150,10 +150,12 @@ // See . const MCSymbol *A = &Target.getSymA()->getSymbol(); - if (!A->getFragment()) - Asm.getContext().reportFatalError(Fixup.getLoc(), + if (!A->getFragment()) { + Asm.getContext().reportError(Fixup.getLoc(), "symbol '" + A->getName() + "' can not be undefined in a subtraction expression"); + return; + } uint32_t Value = Writer->getSymbolAddress(*A, Layout); uint32_t Value2 = 0; @@ -163,10 +165,12 @@ if (const MCSymbolRefExpr *B = Target.getSymB()) { const MCSymbol *SB = &B->getSymbol(); - if (!SB->getFragment()) - Asm.getContext().reportFatalError(Fixup.getLoc(), + if (!SB->getFragment()) { + Asm.getContext().reportError(Fixup.getLoc(), "symbol '" + B->getSymbol().getName() + "' can not be undefined in a subtraction expression"); + return; + } // Select the appropriate difference relocation type. Type = MachO::ARM_RELOC_HALF_SECTDIFF; @@ -251,10 +255,12 @@ // See . const MCSymbol *A = &Target.getSymA()->getSymbol(); - if (!A->getFragment()) - Asm.getContext().reportFatalError(Fixup.getLoc(), + if (!A->getFragment()) { + Asm.getContext().reportError(Fixup.getLoc(), "symbol '" + A->getName() + "' can not be undefined in a subtraction expression"); + return; + } uint32_t Value = Writer->getSymbolAddress(*A, Layout); uint64_t SecAddr = Writer->getSectionAddress(A->getFragment()->getParent()); @@ -265,10 +271,12 @@ assert(Type == MachO::ARM_RELOC_VANILLA && "invalid reloc for 2 symbols"); const MCSymbol *SB = &B->getSymbol(); - if (!SB->getFragment()) - Asm.getContext().reportFatalError(Fixup.getLoc(), + if (!SB->getFragment()) { + Asm.getContext().reportError(Fixup.getLoc(), "symbol '" + B->getSymbol().getName() + "' can not be undefined in a subtraction expression"); + return; + } // Select the appropriate difference relocation type. Type = MachO::ARM_RELOC_SECTDIFF; @@ -346,13 +354,15 @@ unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); unsigned Log2Size; unsigned RelocType = MachO::ARM_RELOC_VANILLA; - if (!getARMFixupKindMachOInfo(Fixup.getKind(), RelocType, Log2Size)) + if (!getARMFixupKindMachOInfo(Fixup.getKind(), RelocType, Log2Size)) { // If we failed to get fixup kind info, it's because there's no legal // relocation type for the fixup kind. This happens when it's a fixup that's // expected to always be resolvable at assembly time and not have any // relocations needed. - Asm.getContext().reportFatalError(Fixup.getLoc(), - "unsupported relocation on symbol"); + Asm.getContext().reportError(Fixup.getLoc(), + "unsupported relocation on symbol"); + return; + } // If this is a difference or a defined symbol plus an offset, then we need a // scattered relocation entry. Differences always require scattered Index: lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -63,15 +63,19 @@ // address range. Forcing a signed division because Value can be negative. Value = (int64_t)Value / 4; // We now check if Value can be encoded as a 16-bit signed immediate. - if (!isInt<16>(Value) && Ctx) - Ctx->reportFatalError(Fixup.getLoc(), "out of range PC16 fixup"); + if (!isInt<16>(Value) && Ctx) { + Ctx->reportError(Fixup.getLoc(), "out of range PC16 fixup"); + return 0; + } break; case Mips::fixup_MIPS_PC19_S2: // Forcing a signed division because Value can be negative. Value = (int64_t)Value / 4; // We now check if Value can be encoded as a 19-bit signed immediate. - if (!isInt<19>(Value) && Ctx) - Ctx->reportFatalError(Fixup.getLoc(), "out of range PC19 fixup"); + if (!isInt<19>(Value) && Ctx) { + Ctx->reportError(Fixup.getLoc(), "out of range PC19 fixup"); + return 0; + } break; case Mips::fixup_Mips_26: // So far we are only using this type for jumps. @@ -104,45 +108,57 @@ // Forcing a signed division because Value can be negative. Value = (int64_t) Value / 2; // We now check if Value can be encoded as a 7-bit signed immediate. - if (!isInt<7>(Value) && Ctx) - Ctx->reportFatalError(Fixup.getLoc(), "out of range PC7 fixup"); + if (!isInt<7>(Value) && Ctx) { + Ctx->reportError(Fixup.getLoc(), "out of range PC7 fixup"); + return 0; + } break; case Mips::fixup_MICROMIPS_PC10_S1: Value -= 2; // Forcing a signed division because Value can be negative. Value = (int64_t) Value / 2; // We now check if Value can be encoded as a 10-bit signed immediate. - if (!isInt<10>(Value) && Ctx) - Ctx->reportFatalError(Fixup.getLoc(), "out of range PC10 fixup"); + if (!isInt<10>(Value) && Ctx) { + Ctx->reportError(Fixup.getLoc(), "out of range PC10 fixup"); + return 0; + } break; case Mips::fixup_MICROMIPS_PC16_S1: Value -= 4; // Forcing a signed division because Value can be negative. Value = (int64_t)Value / 2; // We now check if Value can be encoded as a 16-bit signed immediate. - if (!isInt<16>(Value) && Ctx) - Ctx->reportFatalError(Fixup.getLoc(), "out of range PC16 fixup"); + if (!isInt<16>(Value) && Ctx) { + Ctx->reportError(Fixup.getLoc(), "out of range PC16 fixup"); + return 0; + } break; case Mips::fixup_MIPS_PC18_S3: // Forcing a signed division because Value can be negative. Value = (int64_t)Value / 8; // We now check if Value can be encoded as a 18-bit signed immediate. - if (!isInt<18>(Value) && Ctx) - Ctx->reportFatalError(Fixup.getLoc(), "out of range PC18 fixup"); + if (!isInt<18>(Value) && Ctx) { + Ctx->reportError(Fixup.getLoc(), "out of range PC18 fixup"); + return 0; + } break; case Mips::fixup_MIPS_PC21_S2: // Forcing a signed division because Value can be negative. Value = (int64_t) Value / 4; // We now check if Value can be encoded as a 21-bit signed immediate. - if (!isInt<21>(Value) && Ctx) - Ctx->reportFatalError(Fixup.getLoc(), "out of range PC21 fixup"); + if (!isInt<21>(Value) && Ctx) { + Ctx->reportError(Fixup.getLoc(), "out of range PC21 fixup"); + return 0; + } break; case Mips::fixup_MIPS_PC26_S2: // Forcing a signed division because Value can be negative. Value = (int64_t) Value / 4; // We now check if Value can be encoded as a 26-bit signed immediate. - if (!isInt<26>(Value) && Ctx) - Ctx->reportFatalError(Fixup.getLoc(), "out of range PC26 fixup"); + if (!isInt<26>(Value) && Ctx) { + Ctx->reportError(Fixup.getLoc(), "out of range PC26 fixup"); + return 0; + } break; } Index: lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp =================================================================== --- lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp +++ lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp @@ -241,12 +241,12 @@ if (FixupOffset > 0xffffff) { char Buffer[32]; format("0x%x", FixupOffset).print(Buffer, sizeof(Buffer)); - Asm.getContext().reportFatalError(Fixup.getLoc(), + Asm.getContext().reportError(Fixup.getLoc(), Twine("Section too large, can't encode " "r_address (") + Buffer + ") into 24 bits of scattered " "relocation entry."); - llvm_unreachable("fatal error returned?!"); + return false; } // Is this supposed to follow MCTarget/PPCAsmBackend.cpp:adjustFixupValue()? Index: lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp +++ lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp @@ -175,9 +175,10 @@ // non-relocatable expression. if (A->isUndefined() || B->isUndefined()) { StringRef Name = A->isUndefined() ? A->getName() : B->getName(); - Asm.getContext().reportFatalError(Fixup.getLoc(), + Asm.getContext().reportError(Fixup.getLoc(), "unsupported relocation with subtraction expression, symbol '" + Name + "' can not be undefined in a subtraction expression"); + return; } Value += Writer->getSymbolAddress(*A, Layout) - @@ -387,12 +388,12 @@ if (FixupOffset > 0xffffff) { char Buffer[32]; format("0x%x", FixupOffset).print(Buffer, sizeof(Buffer)); - Asm.getContext().reportFatalError(Fixup.getLoc(), + Asm.getContext().reportError(Fixup.getLoc(), Twine("Section too large, can't encode " "r_address (") + Buffer + ") into 24 bits of scattered " "relocation entry."); - llvm_unreachable("fatal error returned?!"); + return false; } MachO::any_relocation_info MRE; Index: test/MC/AArch64/error-location.s =================================================================== --- test/MC/AArch64/error-location.s +++ test/MC/AArch64/error-location.s @@ -1,5 +1,49 @@ // RUN: not llvm-mc -triple aarch64--none-eabi -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s +// Note: These errors are not always emitted in the order in which the relevant +// source appears, this file is carefully ordered so that that is the case. + .text // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: symbol 'undef' can not be undefined in a subtraction expression .word (0-undef) + +// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: expected relocatable expression + .word -undef + +// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: No relocation available to represent this relative expression + adr x0, #a-undef + +// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Cannot represent a difference across sections + .word x_a - y_a + +// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Cannot represent a subtraction with a weak symbol + .word a - w + +// CHECK: :0: error: expression could not be evaluated + .set v1, -undef + + .comm common, 4 +// 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 + + + +w: + .word 0 + .weak w + + + .section sec_x +x_a: + .word 0 + + + .section sec_y +y_a: + .word 0 Index: test/MC/ARM/arm-elf-relocation-diagnostics.s =================================================================== --- test/MC/ARM/arm-elf-relocation-diagnostics.s +++ test/MC/ARM/arm-elf-relocation-diagnostics.s @@ -8,20 +8,19 @@ @ CHECK: .byte target(sbrel) @ CHECK: ^ -@ TODO: enable these negative test cases -@ .hword target(sbrel) -@ @ CHECK-SBREL-HWORD: error: relocated expression must be 32-bit -@ @ CHECK-SBREL-HWORD: .hword target(sbrel) -@ @ CHECK-SBREL-HWORD: ^ -@ -@ .short target(sbrel) -@ @ CHECK-SBREL-SHORT: error: relocated expression must be 32-bit -@ @ CHECK-SBREL-SHORT: .short target(sbrel) -@ @ CHECK-SBREL-SHORT: ^ -@ -@ .quad target(sbrel) -@ @ CHECK-SBREL-SHORT: error: relocated expression must be 32-bit -@ @ CHECK-SBREL-SHORT: .quad target(sbrel) -@ @ CHECK-SBREL-SHORT: ^ + .hword target(sbrel) +@ CHECK: error: relocated expression must be 32-bit +@ CHECK: .hword target(sbrel) +@ CHECK: ^ + + .short target(sbrel) +@ CHECK: error: relocated expression must be 32-bit +@ CHECK: .short target(sbrel) +@ CHECK: ^ + + .quad target(sbrel) +@ CHECK: error: relocated expression must be 32-bit +@ CHECK: .quad target(sbrel) +@ CHECK: ^ Index: test/MC/ARM/error-location.s =================================================================== --- test/MC/ARM/error-location.s +++ test/MC/ARM/error-location.s @@ -1,5 +1,49 @@ @ RUN: not llvm-mc -triple armv7a--none-eabi -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s +@ Note: These errors are not always emitted in the order in which the relevant +@ source appears, this file is carefully ordered so that that is the case. + .text @ CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: symbol 'undef' can not be undefined in a subtraction expression .word (0-undef) + +@ CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: expected relocatable expression + .word -undef + +@ CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: No relocation available to represent this relative expression + adr r0, #a-undef + +@ CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Cannot represent a difference across sections + .word x_a - y_a + +@ CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: Cannot represent a subtraction with a weak symbol + .word a - w + +@ CHECK: :0: error: expression could not be evaluated + .set v1, -undef + + .comm common, 4 +@ 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 + + + +w: + .word 0 + .weak w + + + .section sec_x +x_a: + .word 0 + + + .section sec_y +y_a: + .word 0 Index: test/MC/ARM/thumb1-relax-adr-local.s =================================================================== --- test/MC/ARM/thumb1-relax-adr-local.s +++ /dev/null @@ -1,9 +0,0 @@ -@ RUN: not llvm-mc -triple thumbv6m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s - - .global func1 - adr r0, Lmisaligned -Lmisaligned: - .word 42 - -@ CHECK-ERROR: misaligned pc-relative fixup value - Index: test/MC/ARM/thumb1-relax-bcc-local.s =================================================================== --- test/MC/ARM/thumb1-relax-bcc-local.s +++ /dev/null @@ -1,6 +0,0 @@ -@ RUN: not llvm-mc -triple thumbv6m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s - - bne Lfar - .space 258 -Lfar: -@ CHECK-ERROR: out of range pc-relative fixup value Index: test/MC/ARM/thumb1-relax-br-local.s =================================================================== --- test/MC/ARM/thumb1-relax-br-local.s +++ /dev/null @@ -1,8 +0,0 @@ -@ RUN: not llvm-mc -triple thumbv6m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s - - b Lfar - .space 2050 - -Lfar: - -@ CHECK-ERROR: out of range pc-relative fixup value Index: test/MC/ARM/thumb1-relax-ldrlit-local-behind.s =================================================================== --- test/MC/ARM/thumb1-relax-ldrlit-local-behind.s +++ /dev/null @@ -1,7 +0,0 @@ -@ RUN: not llvm-mc -triple thumbv6m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s - -Lhere: - ldr r0, Lhere - -@ CHECK-ERROR: out of range pc-relative fixup value - Index: test/MC/ARM/thumb1-relax-ldrlit-local-misaligned.s =================================================================== --- test/MC/ARM/thumb1-relax-ldrlit-local-misaligned.s +++ /dev/null @@ -1,10 +0,0 @@ -@ RUN: not llvm-mc -triple thumbv6m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s - - .global func1 -_func1: - ldr r0, L_misaligned -L_misaligned: - .word 42 - -@ CHECK-ERROR: misaligned pc-relative fixup value - Index: test/MC/ARM/thumb1-relax-ldrlit-local-range.s =================================================================== --- test/MC/ARM/thumb1-relax-ldrlit-local-range.s +++ /dev/null @@ -1,13 +0,0 @@ -@ RUN: not llvm-mc -triple thumbv6m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s - - .global func1 -_func1: - ldr r0, L_far - .space 1024 - - .p2align 2 -L_far: - .word 42 - -@ CHECK-ERROR: out of range pc-relative fixup value - Index: test/MC/ARM/thumb1-relax.s =================================================================== --- /dev/null +++ test/MC/ARM/thumb1-relax.s @@ -0,0 +1,35 @@ +@ RUN: not llvm-mc -triple thumbv6m-none-macho -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s +@ RUN: not llvm-mc -triple thumbv6m-none-eabi -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s + +Lhere: +@ CHECK: out of range pc-relative fixup value + ldr r0, Lhere + +@ CHECK: out of range pc-relative fixup value + b Lfar2 + +@ CHECK: out of range pc-relative fixup value + bne Lfar1 + +@ CHECK: out of range pc-relative fixup value + ldr r0, Lfar2 + +@ CHECK: misaligned pc-relative fixup value + adr r0, Lmisaligned + +@ CHECK: misaligned pc-relative fixup value + ldr r0, Lmisaligned + + .balign 4 + .short 0 +Lmisaligned: + .word 42 + + .space 256 +Lfar1: + .word 42 + + .space 2050 +Lfar2: + .word 42 + Index: test/MC/COFF/bad-expr.s =================================================================== --- test/MC/COFF/bad-expr.s +++ test/MC/COFF/bad-expr.s @@ -1,7 +1,9 @@ // RUN: not llvm-mc -filetype=obj -triple i386-pc-win32 %s 2>&1 | FileCheck %s // CHECK: symbol '__ImageBase' can not be undefined in a subtraction expression +// CHECK: symbol '__ImageBase' can not be undefined in a subtraction expression .data _x: .long _x-__ImageBase + .long __ImageBase-_x Index: test/MC/COFF/invalid-def.s =================================================================== --- test/MC/COFF/invalid-def.s +++ test/MC/COFF/invalid-def.s @@ -1,5 +1,8 @@ -# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s +# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: error: starting a new symbol definition without completing the previous one +# CHECK: error: starting a new symbol definition without completing the previous one .def first .def second + .def third Index: test/MC/COFF/invalid-endef.s =================================================================== --- test/MC/COFF/invalid-endef.s +++ test/MC/COFF/invalid-endef.s @@ -1,4 +1,7 @@ -# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s +# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: ending symbol definition without starting one +# CHECK: ending symbol definition without starting one + .endef .endef Index: test/MC/COFF/invalid-scl-range.s =================================================================== --- test/MC/COFF/invalid-scl-range.s +++ test/MC/COFF/invalid-scl-range.s @@ -1,6 +1,9 @@ # RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s .def storage_class_range +# CHECK: storage class value '1337' out of range +# CHECK: storage class value '9001' out of range .scl 1337 + .scl 9001 .endef Index: test/MC/COFF/invalid-scl.s =================================================================== --- test/MC/COFF/invalid-scl.s +++ test/MC/COFF/invalid-scl.s @@ -1,4 +1,7 @@ -# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s +# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: storage class specified outside of symbol definition +# CHECK: storage class specified outside of symbol definition + .scl 1337 .scl 1337 Index: test/MC/COFF/invalid-type.s =================================================================== --- test/MC/COFF/invalid-type.s +++ test/MC/COFF/invalid-type.s @@ -1,4 +1,7 @@ -# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s +# RUN: not llvm-mc -triple i686-windows -filetype obj -o /dev/null %s 2>&1 | FileCheck %s +# CHECK: symbol type specified outside of a symbol definition +# CHECK: symbol type specified outside of a symbol definition .type 65536 + .type 65537 Index: test/MC/COFF/label-undefined.s =================================================================== --- test/MC/COFF/label-undefined.s +++ test/MC/COFF/label-undefined.s @@ -1,4 +1,6 @@ // RUN: not llvm-mc -filetype=obj -triple i386-pc-win32 %s 2>&1 | FileCheck %s // CHECK: assembler label 'Lundefined' can not be undefined +// CHECK: assembler label 'Lundefined2' can not be undefined .text movl Lundefined, %eax + movl Lundefined2, %eax Index: test/MC/COFF/secidx-diagnostic.s =================================================================== --- test/MC/COFF/secidx-diagnostic.s +++ test/MC/COFF/secidx-diagnostic.s @@ -2,7 +2,9 @@ // RUN: FileCheck %s < %t // CHECK: symbol 'bar' can not be undefined +// CHECK: symbol 'baz' can not be undefined .data foo: .secidx bar + .secidx baz Index: test/MC/ELF/common-error1.s =================================================================== --- test/MC/ELF/common-error1.s +++ test/MC/ELF/common-error1.s @@ -3,4 +3,4 @@ .comm C,4,4 .set A,C -// CHECK: Common symbol C cannot be used in assignment expr +// CHECK: Common symbol 'C' cannot be used in assignment expr Index: test/MC/ELF/common-error2.s =================================================================== --- test/MC/ELF/common-error2.s +++ test/MC/ELF/common-error2.s @@ -3,4 +3,4 @@ .set A,C .comm C,4,4 -// CHECK: Common symbol C cannot be used in assignment expr +// CHECK: Common symbol 'C' cannot be used in assignment expr Index: test/MC/MachO/AArch64/reloc-errors.s =================================================================== --- /dev/null +++ test/MC/MachO/AArch64/reloc-errors.s @@ -0,0 +1,10 @@ +; RUN: not llvm-mc -triple aarch64-none-macho %s -filetype=obj -o - 2>&1 | FileCheck %s + +; CHECK: error: conditional branch requires assembler-local label. 'external' is external. + b.eq external + +; CHECK: error: Invalid relocation on conditional branch + tbz w0, #4, external + +; CHECK: error: unknown AArch64 fixup kind! + adr x0, external Index: test/MC/MachO/ARM/bad-darwin-ARM-reloc.s =================================================================== --- test/MC/MachO/ARM/bad-darwin-ARM-reloc.s +++ test/MC/MachO/ARM/bad-darwin-ARM-reloc.s @@ -7,3 +7,9 @@ L___fcommon: .word 0 @ CHECK-ERROR: unsupported relocation on symbol + +c: + .word a - b +@ CHECK-ERROR: symbol 'a' can not be undefined in a subtraction expression + .word c - b +@ CHECK-ERROR: symbol 'b' can not be undefined in a subtraction expression Index: test/MC/MachO/bad-darwin-x86_64-diff-relocs.s =================================================================== --- test/MC/MachO/bad-darwin-x86_64-diff-relocs.s +++ test/MC/MachO/bad-darwin-x86_64-diff-relocs.s @@ -2,4 +2,12 @@ // RUN: FileCheck --check-prefix=CHECK-ERROR < %t.err %s .quad _foo - _bar -// CHECK-ERROR: unsupported relocation with subtraction expression +// CHECK-ERROR: error: unsupported relocation with subtraction expression + +_Y: +.long (_Y+4)-_b +// CHECK-ERROR: error: unsupported relocation with subtraction expression, symbol '_b' can not be undefined in a subtraction expression + +_Z: +.long (_a+4)-_Z +// CHECK-ERROR: error: unsupported relocation with subtraction expression, symbol '_a' can not be undefined in a subtraction expression Index: test/MC/MachO/bad-darwin-x86_64-reloc-expr1.s =================================================================== --- test/MC/MachO/bad-darwin-x86_64-reloc-expr1.s +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: not llvm-mc -triple x86_64-apple-darwin10 %s -filetype=obj -o - 2> %t.err > %t -// RUN: FileCheck --check-prefix=CHECK-ERROR < %t.err %s - -_Z: -.long (_Z+4)-_b -// CHECK-ERROR: error: unsupported relocation with subtraction expression, symbol '_b' can not be undefined in a subtraction expression Index: test/MC/MachO/bad-darwin-x86_64-reloc-expr2.s =================================================================== --- test/MC/MachO/bad-darwin-x86_64-reloc-expr2.s +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: not llvm-mc -triple x86_64-apple-darwin10 %s -filetype=obj -o - 2> %t.err > %t -// RUN: FileCheck --check-prefix=CHECK-ERROR < %t.err %s - -_Z: -.long (_a+4)-_Z -// CHECK-ERROR: error: unsupported relocation with subtraction expression, symbol '_a' can not be undefined in a subtraction expression Index: test/MC/Mips/micromips-diagnostic-fixup.s =================================================================== --- test/MC/Mips/micromips-diagnostic-fixup.s +++ test/MC/Mips/micromips-diagnostic-fixup.s @@ -1,9 +1,12 @@ # RUN: not llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -arch=mips -mattr=+micromips 2>&1 -filetype=obj | FileCheck %s -# + +# Two instructions, to check that this is not a fatal error +# CHECK: error: out of range PC16 fixup # CHECK: error: out of range PC16 fixup .text b foo + b foo .space 65536 - 6, 1 # -6 = size of b instr plus size of automatically inserted nop nop # This instr makes the branch too long to fit into a 17-bit offset foo: Index: test/MC/Mips/micromips-pc16-fixup.s =================================================================== --- test/MC/Mips/micromips-pc16-fixup.s +++ test/MC/Mips/micromips-pc16-fixup.s @@ -1,6 +1,6 @@ # RUN: llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r2 -arch=mips -mattr=+micromips 2>&1 -filetype=obj | FileCheck %s # -# CHECK-NOT: LLVM ERROR: out of range PC16 fixup +# CHECK-NOT: error: out of range PC16 fixup .text b foo Index: test/MC/Mips/mips-diagnostic-fixup.s =================================================================== --- test/MC/Mips/mips-diagnostic-fixup.s +++ test/MC/Mips/mips-diagnostic-fixup.s @@ -1,9 +1,12 @@ # RUN: not llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -arch=mips 2>&1 -filetype=obj | FileCheck %s -# + +# Two instructions, to check that this is not a fatal error +# CHECK: error: out of range PC16 fixup # CHECK: error: out of range PC16 fixup .text b foo + b foo .space 131072 - 8, 1 # -8 = size of b instr plus size of automatically inserted nop nop # This instr makes the branch too long to fit into a 18-bit offset foo: Index: test/MC/Mips/mips-pc16-fixup.s =================================================================== --- test/MC/Mips/mips-pc16-fixup.s +++ test/MC/Mips/mips-pc16-fixup.s @@ -1,6 +1,6 @@ # RUN: llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r2 -arch=mips 2>&1 -filetype=obj | FileCheck %s # -# CHECK-NOT: LLVM ERROR: out of range PC16 fixup +# CHECK-NOT: error: out of range PC16 fixup .text b foo