Unverified Commit a4051932 authored by Jon Roelofs's avatar Jon Roelofs
Browse files

[MC][AsmParser] Diagnose improperly nested .cfi frames

This showed up when simplifying some large testcase, where the cfi directives
became out of sync with the proc's they enclose.

rdar://111459507

Differential revision: https://reviews.llvm.org/D155245
parent 0fd5dc94
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@ private:
  void *SavedDiagContext;
  std::unique_ptr<MCAsmParserExtension> PlatformParser;
  SMLoc StartTokLoc;
  std::optional<SMLoc> CFIStartProcLoc;

  /// This is the current buffer index we're lexing from as managed by the
  /// SourceMgr object.
@@ -1949,6 +1950,11 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
      Lex();
    }

    if (CFIStartProcLoc && Sym->isExternal())
      return Error(StartTokLoc, "non-private labels cannot appear between "
                                ".cfi_startproc / .cfi_endproc pairs") &&
             Error(*CFIStartProcLoc, "previous .cfi_startproc was here");

    if (discardLTOSymbol(IDVal))
      return false;

@@ -4193,6 +4199,8 @@ bool AsmParser::parseDirectiveCFISections() {
/// parseDirectiveCFIStartProc
/// ::= .cfi_startproc [simple]
bool AsmParser::parseDirectiveCFIStartProc() {
  CFIStartProcLoc = StartTokLoc;

  StringRef Simple;
  if (!parseOptionalToken(AsmToken::EndOfStatement)) {
    if (check(parseIdentifier(Simple) || Simple != "simple",
@@ -4213,8 +4221,11 @@ bool AsmParser::parseDirectiveCFIStartProc() {
/// parseDirectiveCFIEndProc
/// ::= .cfi_endproc
bool AsmParser::parseDirectiveCFIEndProc() {
  CFIStartProcLoc = std::nullopt;

  if (parseEOL())
    return true;

  getStreamer().emitCFIEndProc();
  return false;
}
+23 −0
Original line number Diff line number Diff line
; RUN: not llvm-mc -triple arm64-apple-darwin %s -filetype=obj -o /dev/null 2>&1 | FileCheck %s

; REQUIRES: aarch64-registered-target

	.section	__TEXT,locomotive,regular,pure_instructions

	.globl	_locomotive
	.p2align	2
_locomotive:
	.cfi_startproc
	ret

	; It is invalid to have a non-private label between .cfi_startproc / .cfi_endproc
	.section	__TEXT,__text,regular,pure_instructions
	.globl	_caboose
	.p2align	2
_caboose:
; CHECK: [[#@LINE-1]]:1: error: non-private labels cannot appear between .cfi_startproc / .cfi_endproc pairs
; CHECK: [[#@LINE-9]]:2: error: previous .cfi_startproc was here
	ret
	.cfi_endproc

.subsections_via_symbols
 No newline at end of file