summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-10-10 01:49:21 +0000
committerReid Kleckner <rnk@google.com>2017-10-10 01:49:21 +0000
commit97a2d5c42f24e2544cbddf16cd8841e71e9395e3 (patch)
treede01cdb77fb77ac53f23b58fe9cd257998da6ee4
parent78eb8b912f331d968f69e0b1765449f640ca42a8 (diff)
downloadbcm5719-llvm-97a2d5c42f24e2544cbddf16cd8841e71e9395e3.tar.gz
bcm5719-llvm-97a2d5c42f24e2544cbddf16cd8841e71e9395e3.zip
[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. llvm-svn: 315264
-rw-r--r--llvm/include/llvm/MC/MCStreamer.h3
-rw-r--r--llvm/lib/MC/MCStreamer.cpp104
-rw-r--r--llvm/test/MC/X86/cfi-scope-errors.s18
3 files changed, 84 insertions, 41 deletions
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index e43bc608f0b..8f7189bfc1b 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -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.
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index d414c01fa16..4067df0eaf5 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -206,21 +206,18 @@ MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
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, bool Debug) {
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(MCDwarfFrameInfo &Frame) {
}
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;
}
diff --git a/llvm/test/MC/X86/cfi-scope-errors.s b/llvm/test/MC/X86/cfi-scope-errors.s
new file mode 100644
index 00000000000..a61f817f741
--- /dev/null
+++ b/llvm/test/MC/X86/cfi-scope-errors.s
@@ -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
OpenPOWER on IntegriCloud