[MC] Allow .cfi_sections with empty section list
authorFangrui Song <i@maskray.me>
Fri, 26 Feb 2021 06:29:49 +0000 (22:29 -0800)
committerFangrui Song <i@maskray.me>
Fri, 26 Feb 2021 06:29:49 +0000 (22:29 -0800)
GNU as supports this. This mode silently ignores
.cfi_startproc/.cfi_endproc and .cfi_* in between.

Also drop a diagnostic `in '.cfi_sections' directive`: the diagnostic
already includes the line and it is clear the line is a `.cfi_sections` directive.

llvm/lib/MC/MCParser/AsmParser.cpp
llvm/lib/MC/MCStreamer.cpp
llvm/test/MC/ELF/cfi-sections-empty.s [new file with mode: 0644]
llvm/test/MC/ELF/cfi.s

index 2989041..3d2f0d8 100644 (file)
@@ -4073,29 +4073,20 @@ bool AsmParser::parseDirectiveCFISections() {
   bool EH = false;
   bool Debug = false;
 
-  if (parseIdentifier(Name))
-    return TokError("Expected an identifier");
-
-  if (Name == ".eh_frame")
-    EH = true;
-  else if (Name == ".debug_frame")
-    Debug = true;
-
-  if (getLexer().is(AsmToken::Comma)) {
-    Lex();
-
-    if (parseIdentifier(Name))
-      return TokError("Expected an identifier");
-
-    if (Name == ".eh_frame")
-      EH = true;
-    else if (Name == ".debug_frame")
-      Debug = true;
+  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
+    for (;;) {
+      if (parseIdentifier(Name))
+        return TokError("expected .eh_frame or .debug_frame");
+      if (Name == ".eh_frame")
+        EH = true;
+      else if (Name == ".debug_frame")
+        Debug = true;
+      if (parseOptionalToken(AsmToken::EndOfStatement))
+        break;
+      if (parseToken(AsmToken::Comma))
+        return true;
+    }
   }
-
-  if (parseToken(AsmToken::EndOfStatement))
-    return addErrorSuffix(" in '.cfi_sections' directive");
-
   getStreamer().emitCFISections(EH, Debug);
   return false;
 }
index 9b9e5b9..b2fc542 100644 (file)
@@ -429,9 +429,7 @@ void MCStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
     TS->emitLabel(Symbol);
 }
 
-void MCStreamer::emitCFISections(bool EH, bool Debug) {
-  assert(EH || Debug);
-}
+void MCStreamer::emitCFISections(bool EH, bool Debug) {}
 
 void MCStreamer::emitCFIStartProc(bool IsSimple, SMLoc Loc) {
   if (hasUnfinishedDwarfFrameInfo())
diff --git a/llvm/test/MC/ELF/cfi-sections-empty.s b/llvm/test/MC/ELF/cfi-sections-empty.s
new file mode 100644 (file)
index 0000000..2b4b046
--- /dev/null
@@ -0,0 +1,12 @@
+# RUN: llvm-mc -filetype=obj -triple x86_64 %s | llvm-readelf -S - | FileCheck %s
+
+# CHECK:      Section Headers:
+# CHECK-NOT:  .eh_frame
+# CHECK-NOT:  .debug_frame
+
+.cfi_sections
+
+## .cfi_startproc and .cfi_endproc are ignored.
+.cfi_startproc
+nop
+.cfi_endproc
index d1d9029..8d0a28d 100644 (file)
@@ -438,11 +438,11 @@ f37:
 // CHECK:        }
 
 .ifdef ERR
-// ERR: [[#@LINE+1]]:15: error: Expected an identifier
+// ERR: [[#@LINE+1]]:15: error: expected .eh_frame or .debug_frame
 .cfi_sections $
-// ERR: [[#@LINE+1]]:28: error: unexpected token in '.cfi_sections' directive
+// ERR: [[#@LINE+1]]:28: error: unexpected token
 .cfi_sections .debug_frame $
-// ERR: [[#@LINE+1]]:39: error: unexpected token in '.cfi_sections' directive
+// ERR: [[#@LINE+1]]:39: error: unexpected token
 .cfi_sections .debug_frame, .eh_frame $
 
 // ERR: [[#@LINE+1]]:16: error: unexpected token in '.cfi_startproc' directive