[llvm] r315264 - [MC] Properly diagnose badly scoped .cfi_ directives

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


Author: rnk
Date: Mon Oct  9 18:49:21 2017
New Revision: 315264

URL: http://llvm.org/viewvc/llvm-project?rev=315264&view=rev
Log:
[MC] Properly diagnose badly scoped .cfi_ directives

Removes two report_fatal_errors.

Implement this by removing EmitCFICommon, and do the checking in
getCurrentDwarfFrameInfo. Have the callers check for null before
dereferencing it.

Added:
    llvm/trunk/test/MC/X86/cfi-scope-errors.s
Modified:
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/lib/MC/MCStreamer.cpp

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=315264&r1=315263&r2=315264&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Mon Oct  9 18:49:21 2017
@@ -171,9 +171,6 @@ class MCStreamer {
 
   std::vector<MCDwarfFrameInfo> DwarfFrameInfos;
   MCDwarfFrameInfo *getCurrentDwarfFrameInfo();
-  void EnsureValidDwarfFrame();
-
-  MCSymbol *EmitCFICommon();
 
   /// Similar to DwarfFrameInfos, but for SEH unwind info. Chained frames may
   /// refer to each other, so use std::unique_ptr to provide pointer stability.

Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=315264&r1=315263&r2=315264&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Mon Oct  9 18:49:21 2017
@@ -206,21 +206,18 @@ MCSymbol *MCStreamer::getDwarfLineTableS
   return Table.getLabel();
 }
 
-MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
-  if (DwarfFrameInfos.empty())
-    return nullptr;
-  return &DwarfFrameInfos.back();
-}
-
 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
-  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
-  return CurFrame && !CurFrame->End;
+  return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
 }
 
-void MCStreamer::EnsureValidDwarfFrame() {
-  MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
-  if (!CurFrame || CurFrame->End)
-    report_fatal_error("No open frame");
+MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
+  if (!hasUnfinishedDwarfFrameInfo()) {
+    getContext().reportError(SMLoc(), "this directive must appear between "
+                                      ".cfi_startproc and .cfi_endproc "
+                                      "directives");
+    return nullptr;
+  }
+  return &DwarfFrameInfos.back();
 }
 
 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
@@ -324,7 +321,8 @@ void MCStreamer::EmitCFISections(bool EH
 
 void MCStreamer::EmitCFIStartProc(bool IsSimple) {
   if (hasUnfinishedDwarfFrameInfo())
-    report_fatal_error("Starting a frame before finishing the previous one!");
+    getContext().reportError(
+        SMLoc(), "starting new .cfi frame before finishing the previous one");
 
   MCDwarfFrameInfo Frame;
   Frame.IsSimple = IsSimple;
@@ -347,8 +345,9 @@ void MCStreamer::EmitCFIStartProcImpl(MC
 }
 
 void MCStreamer::EmitCFIEndProc() {
-  EnsureValidDwarfFrame();
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   EmitCFIEndProcImpl(*CurFrame);
 }
 
@@ -364,155 +363,184 @@ MCSymbol *MCStreamer::EmitCFILabel() {
   return (MCSymbol *)1;
 }
 
-MCSymbol *MCStreamer::EmitCFICommon() {
-  EnsureValidDwarfFrame();
-  return EmitCFILabel();
-}
-
 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction =
     MCCFIInstruction::createDefCfa(Label, Register, Offset);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
 }
 
 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction =
     MCCFIInstruction::createDefCfaOffset(Label, Offset);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction =
     MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction =
     MCCFIInstruction::createDefCfaRegister(Label, Register);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
   CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
 }
 
 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction =
     MCCFIInstruction::createOffset(Label, Register, Offset);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction =
     MCCFIInstruction::createRelOffset(Label, Register, Offset);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
                                     unsigned Encoding) {
-  EnsureValidDwarfFrame();
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Personality = Sym;
   CurFrame->PersonalityEncoding = Encoding;
 }
 
 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
-  EnsureValidDwarfFrame();
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Lsda = Sym;
   CurFrame->LsdaEncoding = Encoding;
 }
 
 void MCStreamer::EmitCFIRememberState() {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFIRestoreState() {
   // FIXME: Error if there is no matching cfi_remember_state.
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFISameValue(int64_t Register) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction =
     MCCFIInstruction::createSameValue(Label, Register);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFIRestore(int64_t Register) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction =
     MCCFIInstruction::createRestore(Label, Register);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFIEscape(StringRef Values) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction = 
     MCCFIInstruction::createGnuArgsSize(Label, Size);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFISignalFrame() {
-  EnsureValidDwarfFrame();
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->IsSignalFrame = true;
 }
 
 void MCStreamer::EmitCFIUndefined(int64_t Register) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction =
     MCCFIInstruction::createUndefined(Label, Register);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction =
     MCCFIInstruction::createRegister(Label, Register1, Register2);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFIWindowSave() {
-  MCSymbol *Label = EmitCFICommon();
+  MCSymbol *Label = EmitCFILabel();
   MCCFIInstruction Instruction =
     MCCFIInstruction::createWindowSave(Label);
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->Instructions.push_back(Instruction);
 }
 
 void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
-  EnsureValidDwarfFrame();
   MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+  if (!CurFrame)
+    return;
   CurFrame->RAReg = Register;
 }
 

Added: llvm/trunk/test/MC/X86/cfi-scope-errors.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/cfi-scope-errors.s?rev=315264&view=auto
==============================================================================
--- llvm/trunk/test/MC/X86/cfi-scope-errors.s (added)
+++ llvm/trunk/test/MC/X86/cfi-scope-errors.s Mon Oct  9 18:49:21 2017
@@ -0,0 +1,18 @@
+# RUN: not llvm-mc %s -triple x86_64-linux -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
+
+# FIXME: Push source locations into diagnostics.
+
+.text
+.cfi_def_cfa rsp, 8
+# CHECK: error: this directive must appear between .cfi_startproc and .cfi_endproc directives
+
+.cfi_startproc
+nop
+
+.cfi_startproc
+# CHECK: error: starting new .cfi frame before finishing the previous one
+nop
+.cfi_endproc
+
+.cfi_def_cfa rsp, 8
+# CHECK: error: this directive must appear between .cfi_startproc and .cfi_endproc directives




More information about the llvm-commits mailing list