[llvm] r315262 - [SEH] Use reportError instead of report_fatal_error for bad directives

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 9 18:26:25 PDT 2017


Author: rnk
Date: Mon Oct  9 18:26:25 2017
New Revision: 315262

URL: http://llvm.org/viewvc/llvm-project?rev=315262&view=rev
Log:
[SEH] Use reportError instead of report_fatal_error for bad directives

This makes the .seh_ directives slightly more usable from standalone
assembly files.

This removes a large number of report_fatal_errors and recovers from the
error by ignoring the directive.

Added:
    llvm/trunk/test/MC/AsmParser/seh-directive-errors.s
Modified:
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/include/llvm/MC/MCWinCOFFStreamer.h
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp
    llvm/trunk/lib/MC/MCStreamer.cpp
    llvm/trunk/lib/MC/MCWinCOFFStreamer.cpp
    llvm/trunk/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp
    llvm/trunk/test/MC/COFF/seh-stackalloc-zero.s

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=315262&r1=315261&r2=315262&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Mon Oct  9 18:26:25 2017
@@ -180,7 +180,10 @@ class MCStreamer {
   std::vector<std::unique_ptr<WinEH::FrameInfo>> WinFrameInfos;
 
   WinEH::FrameInfo *CurrentWinFrameInfo;
-  void EnsureValidWinFrameInfo();
+
+  /// Retreive the current frame info if one is available and it is not yet
+  /// closed. Otherwise, issue an error and return null.
+  WinEH::FrameInfo *EnsureValidWinFrameInfo(SMLoc Loc);
 
   /// \brief Tracks an index to represent the order a symbol was emitted in.
   /// Zero means we did not emit that symbol.
@@ -820,20 +823,23 @@ public:
   virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
   virtual void EmitCFIWindowSave();
 
-  virtual void EmitWinCFIStartProc(const MCSymbol *Symbol);
-  virtual void EmitWinCFIEndProc();
-  virtual void EmitWinCFIStartChained();
-  virtual void EmitWinCFIEndChained();
-  virtual void EmitWinCFIPushReg(unsigned Register);
-  virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset);
-  virtual void EmitWinCFIAllocStack(unsigned Size);
-  virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset);
-  virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset);
-  virtual void EmitWinCFIPushFrame(bool Code);
-  virtual void EmitWinCFIEndProlog();
-
-  virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except);
-  virtual void EmitWinEHHandlerData();
+  virtual void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc = SMLoc());
+  virtual void EmitWinCFIEndProc(SMLoc Loc = SMLoc());
+  virtual void EmitWinCFIStartChained(SMLoc Loc = SMLoc());
+  virtual void EmitWinCFIEndChained(SMLoc Loc = SMLoc());
+  virtual void EmitWinCFIPushReg(unsigned Register, SMLoc Loc = SMLoc());
+  virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset,
+                                  SMLoc Loc = SMLoc());
+  virtual void EmitWinCFIAllocStack(unsigned Size, SMLoc Loc = SMLoc());
+  virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset,
+                                 SMLoc Loc = SMLoc());
+  virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
+                                 SMLoc Loc = SMLoc());
+  virtual void EmitWinCFIPushFrame(bool Code, SMLoc Loc = SMLoc());
+  virtual void EmitWinCFIEndProlog(SMLoc Loc = SMLoc());
+  virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
+                                SMLoc Loc = SMLoc());
+  virtual void EmitWinEHHandlerData(SMLoc Loc = SMLoc());
 
   /// Get the .pdata section used for the given section. Typically the given
   /// section is either the main .text section or some other COMDAT .text

Modified: llvm/trunk/include/llvm/MC/MCWinCOFFStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCWinCOFFStreamer.h?rev=315262&r1=315261&r2=315262&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCWinCOFFStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCWinCOFFStreamer.h Mon Oct  9 18:26:25 2017
@@ -61,7 +61,7 @@ public:
   void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
                       unsigned ByteAlignment) override;
   void EmitIdent(StringRef IdentString) override;
-  void EmitWinEHHandlerData() override;
+  void EmitWinEHHandlerData(SMLoc Loc) override;
   void FinishImpl() override;
 
   /// \}

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=315262&r1=315261&r2=315262&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Mon Oct  9 18:26:25 2017
@@ -270,20 +270,24 @@ public:
   void EmitCFIWindowSave() override;
   void EmitCFIReturnColumn(int64_t Register) override;
 
-  void EmitWinCFIStartProc(const MCSymbol *Symbol) override;
-  void EmitWinCFIEndProc() override;
-  void EmitWinCFIStartChained() override;
-  void EmitWinCFIEndChained() override;
-  void EmitWinCFIPushReg(unsigned Register) override;
-  void EmitWinCFISetFrame(unsigned Register, unsigned Offset) override;
-  void EmitWinCFIAllocStack(unsigned Size) override;
-  void EmitWinCFISaveReg(unsigned Register, unsigned Offset) override;
-  void EmitWinCFISaveXMM(unsigned Register, unsigned Offset) override;
-  void EmitWinCFIPushFrame(bool Code) override;
-  void EmitWinCFIEndProlog() override;
-
-  void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) override;
-  void EmitWinEHHandlerData() override;
+  void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
+  void EmitWinCFIEndProc(SMLoc Loc) override;
+  void EmitWinCFIStartChained(SMLoc Loc) override;
+  void EmitWinCFIEndChained(SMLoc Loc) override;
+  void EmitWinCFIPushReg(unsigned Register, SMLoc Loc) override;
+  void EmitWinCFISetFrame(unsigned Register, unsigned Offset,
+                          SMLoc Loc) override;
+  void EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) override;
+  void EmitWinCFISaveReg(unsigned Register, unsigned Offset,
+                         SMLoc Loc) override;
+  void EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
+                         SMLoc Loc) override;
+  void EmitWinCFIPushFrame(bool Code, SMLoc Loc) override;
+  void EmitWinCFIEndProlog(SMLoc Loc) override;
+
+  void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
+                        SMLoc Loc) override;
+  void EmitWinEHHandlerData(SMLoc Loc) override;
 
   void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
                        bool PrintSchedInfo) override;
@@ -1425,38 +1429,38 @@ void MCAsmStreamer::EmitCFIReturnColumn(
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
-  MCStreamer::EmitWinCFIStartProc(Symbol);
+void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
+  MCStreamer::EmitWinCFIStartProc(Symbol, Loc);
 
   OS << ".seh_proc ";
   Symbol->print(OS, MAI);
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinCFIEndProc() {
-  MCStreamer::EmitWinCFIEndProc();
+void MCAsmStreamer::EmitWinCFIEndProc(SMLoc Loc) {
+  MCStreamer::EmitWinCFIEndProc(Loc);
 
   OS << "\t.seh_endproc";
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinCFIStartChained() {
-  MCStreamer::EmitWinCFIStartChained();
+void MCAsmStreamer::EmitWinCFIStartChained(SMLoc Loc) {
+  MCStreamer::EmitWinCFIStartChained(Loc);
 
   OS << "\t.seh_startchained";
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinCFIEndChained() {
-  MCStreamer::EmitWinCFIEndChained();
+void MCAsmStreamer::EmitWinCFIEndChained(SMLoc Loc) {
+  MCStreamer::EmitWinCFIEndChained(Loc);
 
   OS << "\t.seh_endchained";
   EmitEOL();
 }
 
 void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
-                                      bool Except) {
-  MCStreamer::EmitWinEHHandler(Sym, Unwind, Except);
+                                     bool Except, SMLoc Loc) {
+  MCStreamer::EmitWinEHHandler(Sym, Unwind, Except, Loc);
 
   OS << "\t.seh_handler ";
   Sym->print(OS, MAI);
@@ -1467,8 +1471,8 @@ void MCAsmStreamer::EmitWinEHHandler(con
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinEHHandlerData() {
-  MCStreamer::EmitWinEHHandlerData();
+void MCAsmStreamer::EmitWinEHHandlerData(SMLoc Loc) {
+  MCStreamer::EmitWinEHHandlerData(Loc);
 
   // Switch sections. Don't call SwitchSection directly, because that will
   // cause the section switch to be visible in the emitted assembly.
@@ -1483,43 +1487,46 @@ void MCAsmStreamer::EmitWinEHHandlerData
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register) {
-  MCStreamer::EmitWinCFIPushReg(Register);
+void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
+  MCStreamer::EmitWinCFIPushReg(Register, Loc);
 
   OS << "\t.seh_pushreg " << Register;
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
-  MCStreamer::EmitWinCFISetFrame(Register, Offset);
+void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
+                                       SMLoc Loc) {
+  MCStreamer::EmitWinCFISetFrame(Register, Offset, Loc);
 
   OS << "\t.seh_setframe " << Register << ", " << Offset;
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size) {
-  MCStreamer::EmitWinCFIAllocStack(Size);
+void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
+  MCStreamer::EmitWinCFIAllocStack(Size, Loc);
 
   OS << "\t.seh_stackalloc " << Size;
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
-  MCStreamer::EmitWinCFISaveReg(Register, Offset);
+void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
+                                      SMLoc Loc) {
+  MCStreamer::EmitWinCFISaveReg(Register, Offset, Loc);
 
   OS << "\t.seh_savereg " << Register << ", " << Offset;
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
-  MCStreamer::EmitWinCFISaveXMM(Register, Offset);
+void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
+                                      SMLoc Loc) {
+  MCStreamer::EmitWinCFISaveXMM(Register, Offset, Loc);
 
   OS << "\t.seh_savexmm " << Register << ", " << Offset;
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) {
-  MCStreamer::EmitWinCFIPushFrame(Code);
+void MCAsmStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
+  MCStreamer::EmitWinCFIPushFrame(Code, Loc);
 
   OS << "\t.seh_pushframe";
   if (Code)
@@ -1527,8 +1534,8 @@ void MCAsmStreamer::EmitWinCFIPushFrame(
   EmitEOL();
 }
 
-void MCAsmStreamer::EmitWinCFIEndProlog() {
-  MCStreamer::EmitWinCFIEndProlog();
+void MCAsmStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
+  MCStreamer::EmitWinCFIEndProlog(Loc);
 
   OS << "\t.seh_endprologue";
   EmitEOL();

Modified: llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp?rev=315262&r1=315261&r2=315262&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp Mon Oct  9 18:26:25 2017
@@ -568,7 +568,7 @@ bool COFFAsmParser::ParseDirectiveLinkOn
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
+bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc Loc) {
   StringRef SymbolID;
   if (getParser().parseIdentifier(SymbolID))
     return true;
@@ -579,29 +579,29 @@ bool COFFAsmParser::ParseSEHDirectiveSta
   MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
 
   Lex();
-  getStreamer().EmitWinCFIStartProc(Symbol);
+  getStreamer().EmitWinCFIStartProc(Symbol, Loc);
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) {
+bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc Loc) {
   Lex();
-  getStreamer().EmitWinCFIEndProc();
+  getStreamer().EmitWinCFIEndProc(Loc);
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) {
+bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc Loc) {
   Lex();
-  getStreamer().EmitWinCFIStartChained();
+  getStreamer().EmitWinCFIStartChained(Loc);
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
+bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc Loc) {
   Lex();
-  getStreamer().EmitWinCFIEndChained();
+  getStreamer().EmitWinCFIEndChained(Loc);
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
+bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc Loc) {
   StringRef SymbolID;
   if (getParser().parseIdentifier(SymbolID))
     return true;
@@ -623,17 +623,17 @@ bool COFFAsmParser::ParseSEHDirectiveHan
   MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
 
   Lex();
-  getStreamer().EmitWinEHHandler(handler, unwind, except);
+  getStreamer().EmitWinEHHandler(handler, unwind, except, Loc);
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) {
+bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
   Lex();
   getStreamer().EmitWinEHHandlerData();
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
+bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc Loc) {
   unsigned Reg = 0;
   if (ParseSEHRegisterNumber(Reg))
     return true;
@@ -642,11 +642,11 @@ bool COFFAsmParser::ParseSEHDirectivePus
     return TokError("unexpected token in directive");
 
   Lex();
-  getStreamer().EmitWinCFIPushReg(Reg);
+  getStreamer().EmitWinCFIPushReg(Reg, Loc);
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
+bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc Loc) {
   unsigned Reg = 0;
   int64_t Off;
   if (ParseSEHRegisterNumber(Reg))
@@ -655,39 +655,31 @@ bool COFFAsmParser::ParseSEHDirectiveSet
     return TokError("you must specify a stack pointer offset");
 
   Lex();
-  SMLoc startLoc = getLexer().getLoc();
   if (getParser().parseAbsoluteExpression(Off))
     return true;
 
-  if (Off & 0x0F)
-    return Error(startLoc, "offset is not a multiple of 16");
-
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in directive");
 
   Lex();
-  getStreamer().EmitWinCFISetFrame(Reg, Off);
+  getStreamer().EmitWinCFISetFrame(Reg, Off, Loc);
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
+bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
   int64_t Size;
-  SMLoc startLoc = getLexer().getLoc();
   if (getParser().parseAbsoluteExpression(Size))
     return true;
 
-  if (Size & 7)
-    return Error(startLoc, "size is not a multiple of 8");
-
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in directive");
 
   Lex();
-  getStreamer().EmitWinCFIAllocStack(Size);
+  getStreamer().EmitWinCFIAllocStack(Size, Loc);
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
+bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc Loc) {
   unsigned Reg = 0;
   int64_t Off;
   if (ParseSEHRegisterNumber(Reg))
@@ -696,25 +688,21 @@ bool COFFAsmParser::ParseSEHDirectiveSav
     return TokError("you must specify an offset on the stack");
 
   Lex();
-  SMLoc startLoc = getLexer().getLoc();
   if (getParser().parseAbsoluteExpression(Off))
     return true;
 
-  if (Off & 7)
-    return Error(startLoc, "size is not a multiple of 8");
-
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in directive");
 
   Lex();
   // FIXME: Err on %xmm* registers
-  getStreamer().EmitWinCFISaveReg(Reg, Off);
+  getStreamer().EmitWinCFISaveReg(Reg, Off, Loc);
   return false;
 }
 
 // FIXME: This method is inherently x86-specific. It should really be in the
 // x86 backend.
-bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
+bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc Loc) {
   unsigned Reg = 0;
   int64_t Off;
   if (ParseSEHRegisterNumber(Reg))
@@ -723,23 +711,19 @@ bool COFFAsmParser::ParseSEHDirectiveSav
     return TokError("you must specify an offset on the stack");
 
   Lex();
-  SMLoc startLoc = getLexer().getLoc();
   if (getParser().parseAbsoluteExpression(Off))
     return true;
 
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return TokError("unexpected token in directive");
 
-  if (Off & 0x0F)
-    return Error(startLoc, "offset is not a multiple of 16");
-
   Lex();
   // FIXME: Err on non-%xmm* registers
-  getStreamer().EmitWinCFISaveXMM(Reg, Off);
+  getStreamer().EmitWinCFISaveXMM(Reg, Off, Loc);
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
+bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc Loc) {
   bool Code = false;
   StringRef CodeID;
   if (getLexer().is(AsmToken::At)) {
@@ -756,13 +740,13 @@ bool COFFAsmParser::ParseSEHDirectivePus
     return TokError("unexpected token in directive");
 
   Lex();
-  getStreamer().EmitWinCFIPushFrame(Code);
+  getStreamer().EmitWinCFIPushFrame(Code, Loc);
   return false;
 }
 
-bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
+bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
   Lex();
-  getStreamer().EmitWinCFIEndProlog();
+  getStreamer().EmitWinCFIEndProlog(Loc);
   return false;
 }
 

Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=315262&r1=315261&r2=315262&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Mon Oct  9 18:26:25 2017
@@ -516,20 +516,29 @@ void MCStreamer::EmitCFIReturnColumn(int
   CurFrame->RAReg = Register;
 }
 
-void MCStreamer::EnsureValidWinFrameInfo() {
+WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
   const MCAsmInfo *MAI = Context.getAsmInfo();
-  if (!MAI->usesWindowsCFI())
-    report_fatal_error(".seh_* directives are not supported on this target");
-  if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End)
-    report_fatal_error("No open Win64 EH frame function!");
+  if (!MAI->usesWindowsCFI()) {
+    getContext().reportError(
+        Loc, ".seh_* directives are not supported on this target");
+    return nullptr;
+  }
+  if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
+    getContext().reportError(
+        Loc, ".seh_ directive must appear within an active frame");
+    return nullptr;
+  }
+  return CurrentWinFrameInfo;
 }
 
-void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
+void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
   const MCAsmInfo *MAI = Context.getAsmInfo();
   if (!MAI->usesWindowsCFI())
-    report_fatal_error(".seh_* directives are not supported on this target");
+    return getContext().reportError(
+        Loc, ".seh_* directives are not supported on this target");
   if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
-    report_fatal_error("Starting a function before ending the previous one!");
+    getContext().reportError(
+        Loc, "Starting a function before ending the previous one!");
 
   MCSymbol *StartProc = EmitCFILabel();
 
@@ -539,56 +548,67 @@ void MCStreamer::EmitWinCFIStartProc(con
   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
 }
 
-void MCStreamer::EmitWinCFIEndProc() {
-  EnsureValidWinFrameInfo();
-  if (CurrentWinFrameInfo->ChainedParent)
-    report_fatal_error("Not all chained regions terminated!");
+void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
+  if (CurFrame->ChainedParent)
+    getContext().reportError(Loc, "Not all chained regions terminated!");
 
   MCSymbol *Label = EmitCFILabel();
-  CurrentWinFrameInfo->End = Label;
+  CurFrame->End = Label;
 }
 
-void MCStreamer::EmitWinCFIStartChained() {
-  EnsureValidWinFrameInfo();
+void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
 
   MCSymbol *StartProc = EmitCFILabel();
 
   WinFrameInfos.emplace_back(llvm::make_unique<WinEH::FrameInfo>(
-      CurrentWinFrameInfo->Function, StartProc, CurrentWinFrameInfo));
+      CurFrame->Function, StartProc, CurFrame));
   CurrentWinFrameInfo = WinFrameInfos.back().get();
   CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
 }
 
-void MCStreamer::EmitWinCFIEndChained() {
-  EnsureValidWinFrameInfo();
-  if (!CurrentWinFrameInfo->ChainedParent)
-    report_fatal_error("End of a chained region outside a chained region!");
+void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
+  if (!CurFrame->ChainedParent)
+    return getContext().reportError(
+        Loc, "End of a chained region outside a chained region!");
 
   MCSymbol *Label = EmitCFILabel();
 
-  CurrentWinFrameInfo->End = Label;
-  CurrentWinFrameInfo =
-      const_cast<WinEH::FrameInfo *>(CurrentWinFrameInfo->ChainedParent);
+  CurFrame->End = Label;
+  CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
 }
 
-void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
-                                  bool Except) {
-  EnsureValidWinFrameInfo();
-  if (CurrentWinFrameInfo->ChainedParent)
-    report_fatal_error("Chained unwind areas can't have handlers!");
-  CurrentWinFrameInfo->ExceptionHandler = Sym;
+void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
+                                  SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
+  if (CurFrame->ChainedParent)
+    return getContext().reportError(
+        Loc, "Chained unwind areas can't have handlers!");
+  CurFrame->ExceptionHandler = Sym;
   if (!Except && !Unwind)
-    report_fatal_error("Don't know what kind of handler this is!");
+    getContext().reportError(Loc, "Don't know what kind of handler this is!");
   if (Unwind)
-    CurrentWinFrameInfo->HandlesUnwind = true;
+    CurFrame->HandlesUnwind = true;
   if (Except)
-    CurrentWinFrameInfo->HandlesExceptions = true;
+    CurFrame->HandlesExceptions = true;
 }
 
-void MCStreamer::EmitWinEHHandlerData() {
-  EnsureValidWinFrameInfo();
-  if (CurrentWinFrameInfo->ChainedParent)
-    report_fatal_error("Chained unwind areas can't have handlers!");
+void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
+  if (CurFrame->ChainedParent)
+    getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
 }
 
 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
@@ -625,86 +645,110 @@ MCSection *MCStreamer::getAssociatedXDat
 
 void MCStreamer::EmitSyntaxDirective() {}
 
-void MCStreamer::EmitWinCFIPushReg(unsigned Register) {
-  EnsureValidWinFrameInfo();
+void MCStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
 
   MCSymbol *Label = EmitCFILabel();
 
   WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
-  CurrentWinFrameInfo->Instructions.push_back(Inst);
+  CurFrame->Instructions.push_back(Inst);
 }
 
-void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
-  EnsureValidWinFrameInfo();
-  if (CurrentWinFrameInfo->LastFrameInst >= 0)
-    report_fatal_error("Frame register and offset already specified!");
+void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
+                                    SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
+  if (CurFrame->LastFrameInst >= 0)
+    return getContext().reportError(
+        Loc, "frame register and offset can be set at most once");
   if (Offset & 0x0F)
-    report_fatal_error("Misaligned frame pointer offset!");
+    return getContext().reportError(Loc, "offset is not a multiple of 16");
   if (Offset > 240)
-    report_fatal_error("Frame offset must be less than or equal to 240!");
+    return getContext().reportError(
+        Loc, "frame offset must be less than or equal to 240");
 
   MCSymbol *Label = EmitCFILabel();
 
   WinEH::Instruction Inst =
       Win64EH::Instruction::SetFPReg(Label, Register, Offset);
-  CurrentWinFrameInfo->LastFrameInst = CurrentWinFrameInfo->Instructions.size();
-  CurrentWinFrameInfo->Instructions.push_back(Inst);
+  CurFrame->LastFrameInst = CurFrame->Instructions.size();
+  CurFrame->Instructions.push_back(Inst);
 }
 
-void MCStreamer::EmitWinCFIAllocStack(unsigned Size) {
-  EnsureValidWinFrameInfo();
+void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
   if (Size == 0)
-    report_fatal_error("Allocation size must be non-zero!");
+    return getContext().reportError(Loc,
+                                    "stack allocation size must be non-zero");
   if (Size & 7)
-    report_fatal_error("Misaligned stack allocation!");
+    return getContext().reportError(
+        Loc, "stack allocation size is not a multiple of 8");
 
   MCSymbol *Label = EmitCFILabel();
 
   WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
-  CurrentWinFrameInfo->Instructions.push_back(Inst);
+  CurFrame->Instructions.push_back(Inst);
 }
 
-void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
-  EnsureValidWinFrameInfo();
+void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
+                                   SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
+
   if (Offset & 7)
-    report_fatal_error("Misaligned saved register offset!");
+    return getContext().reportError(
+        Loc, "register save offset is not 8 byte aligned");
 
   MCSymbol *Label = EmitCFILabel();
 
   WinEH::Instruction Inst =
       Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
-  CurrentWinFrameInfo->Instructions.push_back(Inst);
+  CurFrame->Instructions.push_back(Inst);
 }
 
-void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
-  EnsureValidWinFrameInfo();
+void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
+                                   SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
   if (Offset & 0x0F)
-    report_fatal_error("Misaligned saved vector register offset!");
+    return getContext().reportError(Loc, "offset is not a multiple of 16");
 
   MCSymbol *Label = EmitCFILabel();
 
   WinEH::Instruction Inst =
       Win64EH::Instruction::SaveXMM(Label, Register, Offset);
-  CurrentWinFrameInfo->Instructions.push_back(Inst);
+  CurFrame->Instructions.push_back(Inst);
 }
 
-void MCStreamer::EmitWinCFIPushFrame(bool Code) {
-  EnsureValidWinFrameInfo();
-  if (!CurrentWinFrameInfo->Instructions.empty())
-    report_fatal_error("If present, PushMachFrame must be the first UOP");
+void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
+  if (!CurFrame->Instructions.empty())
+    return getContext().reportError(
+        Loc, "If present, PushMachFrame must be the first UOP");
 
   MCSymbol *Label = EmitCFILabel();
 
   WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
-  CurrentWinFrameInfo->Instructions.push_back(Inst);
+  CurFrame->Instructions.push_back(Inst);
 }
 
-void MCStreamer::EmitWinCFIEndProlog() {
-  EnsureValidWinFrameInfo();
+void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
+  WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
+  if (!CurFrame)
+    return;
 
   MCSymbol *Label = EmitCFILabel();
 
-  CurrentWinFrameInfo->PrologEnd = Label;
+  CurFrame->PrologEnd = Label;
 }
 
 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
@@ -734,9 +778,9 @@ void MCStreamer::EmitWindowsUnwindTables
 
 void MCStreamer::Finish() {
   if (!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End)
-    report_fatal_error("Unfinished frame!");
+    getContext().reportError(SMLoc(), "Unfinished frame!");
   if (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)
-    report_fatal_error("Unfinished frame!");
+    getContext().reportError(SMLoc(), "Unfinished frame!");
 
   MCTargetStreamer *TS = getTargetStreamer();
   if (TS)

Modified: llvm/trunk/lib/MC/MCWinCOFFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCWinCOFFStreamer.cpp?rev=315262&r1=315261&r2=315262&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCWinCOFFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCWinCOFFStreamer.cpp Mon Oct  9 18:26:25 2017
@@ -285,7 +285,7 @@ void MCWinCOFFStreamer::EmitIdent(String
   llvm_unreachable("not implemented");
 }
 
-void MCWinCOFFStreamer::EmitWinEHHandlerData() {
+void MCWinCOFFStreamer::EmitWinEHHandlerData(SMLoc Loc) {
   llvm_unreachable("not implemented");
 }
 

Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp?rev=315262&r1=315261&r2=315262&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86WinCOFFStreamer.cpp Mon Oct  9 18:26:25 2017
@@ -21,13 +21,13 @@ public:
                      raw_pwrite_stream &OS)
       : MCWinCOFFStreamer(C, AB, *CE, OS) {}
 
-  void EmitWinEHHandlerData() override;
+  void EmitWinEHHandlerData(SMLoc Loc) override;
   void EmitWindowsUnwindTables() override;
   void FinishImpl() override;
 };
 
-void X86WinCOFFStreamer::EmitWinEHHandlerData() {
-  MCStreamer::EmitWinEHHandlerData();
+void X86WinCOFFStreamer::EmitWinEHHandlerData(SMLoc Loc) {
+  MCStreamer::EmitWinEHHandlerData(Loc);
 
   // We have to emit the unwind info now, because this directive
   // actually switches to the .xdata section!

Added: llvm/trunk/test/MC/AsmParser/seh-directive-errors.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/seh-directive-errors.s?rev=315262&view=auto
==============================================================================
--- llvm/trunk/test/MC/AsmParser/seh-directive-errors.s (added)
+++ llvm/trunk/test/MC/AsmParser/seh-directive-errors.s Mon Oct  9 18:26:25 2017
@@ -0,0 +1,96 @@
+# RUN: not llvm-mc %s -filetype=obj -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
+	.text
+
+	.seh_pushreg 6
+	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: .seh_ directive must appear within an active frame
+
+	.seh_stackalloc 32
+	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: .seh_ directive must appear within an active frame
+
+	.def	 f;
+	.scl	2;
+	.type	32;
+	.endef
+	.globl	f                       # -- Begin function f
+	.p2align	4, 0x90
+f:                                      # @f
+.seh_proc f
+	pushq	%rsi
+	.seh_pushreg 6
+	pushq	%rdi
+	.seh_pushreg 7
+	pushq	%rbx
+	.seh_pushreg 3
+	subq	$32, %rsp
+	.seh_stackalloc 0
+	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: stack allocation size must be non-zero
+	.seh_stackalloc 7
+	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: stack allocation size is not a multiple of 8
+	.seh_stackalloc 32
+	.seh_endprologue
+	nop
+	addq	$32, %rsp
+	popq	%rbx
+	popq	%rdi
+	popq	%rsi
+	retq
+	.seh_handlerdata
+	.text
+	.seh_endproc
+
+
+	.seh_pushreg 6
+	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: .seh_ directive must appear within an active frame
+
+g:
+	.seh_proc g
+	pushq %rbp
+	.seh_pushreg 3
+	pushq %rsi
+	.seh_pushreg 6
+	.seh_endprologue
+	.seh_setframe 3 255
+	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: you must specify a stack pointer offset
+	.seh_setframe 3, 255
+	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: offset is not a multiple of 16
+	.seh_setframe 3, 256
+	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: frame offset must be less than or equal to 240
+	.seh_setframe 3, 128
+	.seh_setframe 3, 128
+	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: frame register and offset can be set at most once
+	nop
+	popq %rsi
+	popq %rbp
+	retq
+	.seh_endproc
+
+        .globl  h                       # -- Begin function h
+        .p2align        4, 0x90
+h:                                      # @h
+.seh_proc h
+# BB#0:                                 # %entry
+        subq    $72, %rsp
+        .seh_stackalloc 72
+        movaps  %xmm7, 48(%rsp)         # 16-byte Spill
+        .seh_savexmm 7 44
+	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: you must specify an offset on the stack
+        .seh_savexmm 7, 44
+	# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: offset is not a multiple of 16
+        .seh_savexmm 7, 48
+        movaps  %xmm6, 32(%rsp)         # 16-byte Spill
+        .seh_savexmm 6, 32
+        .seh_endprologue
+        movapd  %xmm0, %xmm6
+        callq   getdbl
+        movapd  %xmm0, %xmm7
+        addsd   %xmm6, %xmm7
+        callq   getdbl
+        addsd   %xmm7, %xmm0
+        movaps  32(%rsp), %xmm6         # 16-byte Reload
+        movaps  48(%rsp), %xmm7         # 16-byte Reload
+        addq    $72, %rsp
+        retq
+        .seh_handlerdata
+        .text
+        .seh_endproc
+                                        # -- End function

Modified: llvm/trunk/test/MC/COFF/seh-stackalloc-zero.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/seh-stackalloc-zero.s?rev=315262&r1=315261&r2=315262&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/seh-stackalloc-zero.s (original)
+++ llvm/trunk/test/MC/COFF/seh-stackalloc-zero.s Mon Oct  9 18:26:25 2017
@@ -1,11 +1,10 @@
 // RUN: not llvm-mc -triple x86_64-pc-win32 -filetype=obj %s -o %t.o 2>&1 | FileCheck %s
 
-// CHECK: Allocation size must be non-zero!
-
     .globl smallFunc
     .def smallFunc; .scl 2; .type 32; .endef
     .seh_proc smallFunc
     .seh_stackalloc 0
+// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: stack allocation size must be non-zero
 smallFunc:
     ret
     .seh_endproc




More information about the llvm-commits mailing list