Skip to content

Commit 340fb65

Browse files
authored
[TableGen] Detect invalid -D arguments and fail (llvm#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.
1 parent f357fe3 commit 340fb65

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

llvm/lib/TableGen/TGLexer.cpp

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,25 @@ constexpr PreprocessorDir PreprocessorDirs[] = {{tgtok::Ifdef, "ifdef"},
4444
{tgtok::Endif, "endif"},
4545
{tgtok::Define, "define"}};
4646

47+
// Returns a pointer past the end of a valid macro name at the start of `Str`.
48+
// Valid macro names match the regular expression [a-zA-Z_][0-9a-zA-Z_]*.
49+
static const char *lexMacroName(StringRef Str) {
50+
assert(!Str.empty());
51+
52+
// Macro names start with [a-zA-Z_].
53+
const char *Next = Str.begin();
54+
if (*Next != '_' && !isalpha(*Next))
55+
return Next;
56+
// Eat the first character of the name.
57+
++Next;
58+
59+
// Match the rest of the identifier regex: [0-9a-zA-Z_]*
60+
const char *End = Str.end();
61+
while (Next != End && (isalpha(*Next) || isdigit(*Next) || *Next == '_'))
62+
++Next;
63+
return Next;
64+
}
65+
4766
TGLexer::TGLexer(SourceMgr &SM, ArrayRef<std::string> Macros) : SrcMgr(SM) {
4867
CurBuffer = SrcMgr.getMainFileID();
4968
CurBuf = SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer();
@@ -54,9 +73,16 @@ TGLexer::TGLexer(SourceMgr &SM, ArrayRef<std::string> Macros) : SrcMgr(SM) {
5473
PrepIncludeStack.push_back(
5574
std::make_unique<std::vector<PreprocessorControlDesc>>());
5675

57-
// Put all macros defined in the command line into the DefinedMacros set.
58-
for (const std::string &MacroName : Macros)
76+
// Add all macros defined on the command line to the DefinedMacros set.
77+
// Check invalid macro names and print fatal error if we find one.
78+
for (StringRef MacroName : Macros) {
79+
const char *End = lexMacroName(MacroName);
80+
if (End != MacroName.end())
81+
PrintFatalError("Invalid macro name `" + MacroName +
82+
"` specified on command line");
83+
5984
DefinedMacros.insert(MacroName);
85+
}
6086
}
6187

6288
SMLoc TGLexer::getLoc() const {
@@ -699,9 +725,8 @@ bool TGLexer::prepEatPreprocessorDirective(tgtok::TokKind Kind) {
699725
return false;
700726
}
701727

702-
tgtok::TokKind TGLexer::lexPreprocessor(
703-
tgtok::TokKind Kind, bool ReturnNextLiveToken) {
704-
728+
tgtok::TokKind TGLexer::lexPreprocessor(tgtok::TokKind Kind,
729+
bool ReturnNextLiveToken) {
705730
// We must be looking at a preprocessing directive. Eat it!
706731
if (!prepEatPreprocessorDirective(Kind))
707732
PrintFatalError("lexPreprocessor() called for unknown "
@@ -901,14 +926,7 @@ StringRef TGLexer::prepLexMacroName() {
901926
++CurPtr;
902927

903928
TokStart = CurPtr;
904-
// Macro names start with [a-zA-Z_].
905-
if (*CurPtr != '_' && !isalpha(*CurPtr))
906-
return "";
907-
908-
// Match the rest of the identifier regex: [0-9a-zA-Z_]*
909-
while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_')
910-
++CurPtr;
911-
929+
CurPtr = lexMacroName(StringRef(CurPtr, CurBuf.end() - CurPtr));
912930
return StringRef(TokStart, CurPtr - TokStart);
913931
}
914932

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: not llvm-tblgen %s -DMACRO=1 2>&1 | FileCheck %s --check-prefix=CHECK-TEST-1
2+
// RUN: not llvm-tblgen %s -D0MAC 2>&1 | FileCheck %s --check-prefix=CHECK-TEST-2
3+
// RUN: not llvm-tblgen %s -D_MAC# 2>&1 | FileCheck %s --check-prefix=CHECK-TEST-3
4+
// RUN: not llvm-tblgen %s -D 2>&1 | FileCheck %s --check-prefix=CHECK-TEST-4
5+
6+
// CHECK-TEST-1: error: Invalid macro name `MACRO=1` specified on command line
7+
// CHECK-TEST-2: error: Invalid macro name `0MAC` specified on command line
8+
// CHECK-TEST-3: error: Invalid macro name `_MAC#` specified on command line
9+
// CHECK-TEST-4: for the -D option: requires a value!

0 commit comments

Comments
 (0)