Skip to content

Commit c74f7d8

Browse files
committed
[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.
1 parent b7c7dbd commit c74f7d8

File tree

2 files changed

+42
-13
lines changed

2 files changed

+42
-13
lines changed

llvm/lib/TableGen/TGLexer.cpp

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,26 @@ struct {
4444
};
4545
} // end anonymous namespace
4646

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

57-
// Put all macros defined in the command line into the DefinedMacros set.
58-
for (const std::string &MacroName : Macros)
77+
// Add all macros defined on the command line to the DefinedMacros set.
78+
// Check invalid macro names and print fatal error if we find one.
79+
for (const std::string &MacroName : Macros) {
80+
const char *Begin = MacroName.c_str();
81+
const char *End = lexMacroName(Begin);
82+
if (static_cast<size_t>(std::distance(Begin, End)) != MacroName.size())
83+
PrintFatalError(Twine("Invalid macro name `") + Twine(MacroName) +
84+
Twine("` specified on command line."));
85+
5986
DefinedMacros.insert(MacroName);
87+
}
6088
}
6189

6290
SMLoc TGLexer::getLoc() const {
@@ -710,9 +738,8 @@ bool TGLexer::prepEatPreprocessorDirective(tgtok::TokKind Kind) {
710738
return false;
711739
}
712740

713-
tgtok::TokKind TGLexer::lexPreprocessor(
714-
tgtok::TokKind Kind, bool ReturnNextLiveToken) {
715-
741+
tgtok::TokKind TGLexer::lexPreprocessor(tgtok::TokKind Kind,
742+
bool ReturnNextLiveToken) {
716743
// We must be looking at a preprocessing directive. Eat it!
717744
if (!prepEatPreprocessorDirective(Kind))
718745
PrintFatalError("lexPreprocessor() called for unknown "
@@ -912,14 +939,7 @@ StringRef TGLexer::prepLexMacroName() {
912939
++CurPtr;
913940

914941
TokStart = CurPtr;
915-
// Macro names start with [a-zA-Z_].
916-
if (*CurPtr != '_' && !isalpha(*CurPtr))
917-
return "";
918-
919-
// Match the rest of the identifier regex: [0-9a-zA-Z_]*
920-
while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_')
921-
++CurPtr;
922-
942+
CurPtr = lexMacroName(CurPtr);
923943
return StringRef(TokStart, CurPtr - TokStart);
924944
}
925945

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)