[llvm] [TableGen] Detect invalid -D arguments and fail. (PR #102813)

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 11 06:36:46 PDT 2024


https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/102813

- Detect invalid macro names specified on command line and fail if one found.
- Specifically, -DXYZ=1 for example, will fail instead is being silently accepted.

>From 1ee7426f93446454f27adc63a82a8aeaf5a91ad7 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Sun, 11 Aug 2024 06:05:56 -0700
Subject: [PATCH] [TableGen] Detect invalid -D arguments and fail.

- Detect invalid macro names specified on command line and fail if one
  found.
- Specifically, -DXYZ=1 for example, will fail instead is being silently
  accepted.
---
 llvm/lib/TableGen/TGLexer.cpp                 | 30 +++++++++++++++++--
 .../invalid-macro-name-command-line.td        |  9 ++++++
 2 files changed, 37 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/TableGen/invalid-macro-name-command-line.td

diff --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index 99d866a23a68ba..e3f9408c61fed0 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -42,6 +42,25 @@ struct {
   { tgtok::Endif, "endif" },
   { tgtok::Define, "define" }
 };
+
+// Returns true if `MacroName` is a valid macro name. Valid macro names match
+// the regular expression [a-zA-Z_][0-9a-zA-Z_]* (see prepLexMacroName).
+bool IsValidMacroName(StringRef MacroName) {
+  if (MacroName.size() == 0)
+    return false;
+
+  char First = MacroName[0];
+  if (First != '_' && !isalpha(First))
+    return false;
+
+  // Match the rest of the identifier regex: [0-9a-zA-Z_]*
+  for (char Rest : MacroName.drop_front())
+    if (Rest != '_' && !isalpha(Rest) && !isdigit(Rest))
+      return false;
+
+  return true;
+}
+
 } // end anonymous namespace
 
 TGLexer::TGLexer(SourceMgr &SM, ArrayRef<std::string> Macros) : SrcMgr(SM) {
@@ -54,9 +73,16 @@ TGLexer::TGLexer(SourceMgr &SM, ArrayRef<std::string> Macros) : SrcMgr(SM) {
   PrepIncludeStack.push_back(
       std::make_unique<std::vector<PreprocessorControlDesc>>());
 
-  // Put all macros defined in the command line into the DefinedMacros set.
-  for (const std::string &MacroName : Macros)
+  // Add all macros defined on the command line to the DefinedMacros set.
+  // TableGen does not support macros with values (-DXYZ=1), warn if we see
+  // such a macro, and reject it.
+  for (const std::string &MacroName : Macros) {
+    if (!IsValidMacroName(MacroName))
+      PrintFatalError(Twine("Invalid macro name `") + Twine(MacroName) +
+                      Twine("` specified on command line."));
+
     DefinedMacros.insert(MacroName);
+  }
 }
 
 SMLoc TGLexer::getLoc() const {
diff --git a/llvm/test/TableGen/invalid-macro-name-command-line.td b/llvm/test/TableGen/invalid-macro-name-command-line.td
new file mode 100644
index 00000000000000..eafa96b0236889
--- /dev/null
+++ b/llvm/test/TableGen/invalid-macro-name-command-line.td
@@ -0,0 +1,9 @@
+// RUN: not llvm-tblgen %s -DMACRO=1 2>&1 | FileCheck %s --check-prefix=CHECK-TEST-1
+// RUN: not llvm-tblgen %s -D0MAC 2>&1 | FileCheck %s --check-prefix=CHECK-TEST-2
+// RUN: not llvm-tblgen %s -D_MAC# 2>&1 | FileCheck %s --check-prefix=CHECK-TEST-3
+// RUN: not llvm-tblgen %s -D 2>&1 | FileCheck %s --check-prefix=CHECK-TEST-4
+
+// CHECK-TEST-1: error: Invalid macro name `MACRO=1` specified on command line.
+// CHECK-TEST-2: error: Invalid macro name `0MAC` specified on command line.
+// CHECK-TEST-3: error: Invalid macro name `_MAC#` specified on command line.
+// CHECK-TEST-4: for the -D option: requires a value!



More information about the llvm-commits mailing list