summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp21
-rw-r--r--llvm/test/MC/AsmParser/macro-max-depth.s20
2 files changed, 37 insertions, 4 deletions
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 8f2ee7f1163..d85f1c613c7 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -34,6 +34,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -41,12 +42,17 @@
#include "llvm/Support/raw_ostream.h"
#include <cctype>
#include <deque>
+#include <sstream>
#include <string>
#include <vector>
using namespace llvm;
MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {}
+static cl::opt<unsigned> AsmMacroMaxNestingDepth(
+ "asm-macro-max-nesting-depth", cl::init(20), cl::Hidden,
+ cl::desc("The maximum nesting depth allowed for assembly macros."));
+
namespace {
/// \brief Helper types for tracking macro definitions.
typedef std::vector<AsmToken> MCAsmMacroArgument;
@@ -2363,10 +2369,17 @@ void AsmParser::defineMacro(StringRef Name, MCAsmMacro Macro) {
void AsmParser::undefineMacro(StringRef Name) { MacroMap.erase(Name); }
bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
- // Arbitrarily limit macro nesting depth, to match 'as'. We can eliminate
- // this, although we should protect against infinite loops.
- if (ActiveMacros.size() == 20)
- return TokError("macros cannot be nested more than 20 levels deep");
+ // Arbitrarily limit macro nesting depth (default matches 'as'). We can
+ // eliminate this, although we should protect against infinite loops.
+ unsigned MaxNestingDepth = AsmMacroMaxNestingDepth;
+ if (ActiveMacros.size() == MaxNestingDepth) {
+ std::ostringstream MaxNestingDepthError;
+ MaxNestingDepthError << "macros cannot be nested more than "
+ << MaxNestingDepth << " levels deep."
+ << " Use -asm-macro-max-nesting-depth to increase "
+ "this limit.";
+ return TokError(MaxNestingDepthError.str());
+ }
MCAsmMacroArguments A;
if (parseMacroArguments(M, A))
diff --git a/llvm/test/MC/AsmParser/macro-max-depth.s b/llvm/test/MC/AsmParser/macro-max-depth.s
new file mode 100644
index 00000000000..47fbf9a1930
--- /dev/null
+++ b/llvm/test/MC/AsmParser/macro-max-depth.s
@@ -0,0 +1,20 @@
+// RUN: llvm-mc -triple x86_64-unknown-unknown -asm-macro-max-nesting-depth=42 %s | FileCheck %s -check-prefix=CHECK_PASS
+// RUN: not llvm-mc -triple x86_64-unknown-unknown %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK_FAIL < %t %s
+
+.macro rec head, tail:vararg
+ .ifnb \tail
+ rec \tail
+ .else
+ .long 42
+ .endif
+.endm
+
+.macro amplify macro, args:vararg
+ \macro \args \args \args \args
+.endm
+
+amplify rec 0 0 0 0 0 0 0 0 0 0
+
+// CHECK_PASS: .long 42
+// CHECK_FAIL: error: macros cannot be nested more than {{[0-9]+}} levels deep. Use -asm-macro-max-nesting-depth to increase this limit.
OpenPOWER on IntegriCloud