forked from OSchip/llvm-project
[FileCheck] Don't diagnose undef vars at parse time
Summary: Diagnosing use of undefined variables takes place in parseNumericVariableUse() and printSubstitutions() for numeric variables but only takes place in printSubstitutions() for string variables. The reason for the split location of diagnostics is that parsing is not aware of the clearing of variables due to --enable-var-scope and thus use of variables cleared in this way can only be catched by printSubstitutions(). Beyond the code level inconsistency, there is also a user facing inconsistency since diagnostics look different between the two functions. While the diagnostic in printSubstitutions is more verbose, doing the diagnostic there allows to diagnose all undefined variables rather than just the first one and error out. This patch create dummy variable definition when encountering a use of undefined variable so that parsing can proceed and be diagnosed by printSubstitutions() later. Tests that were testing whether parsing fails in such case are thus modified accordingly. Reviewers: jhenderson, chandlerc, jdenny, probinson, grimar, arichardson, rnk Subscribers: JonChesterfield, rogfer01, hfinkel, kristina, rnk, tra, arichardson, grimar, dblaikie, probinson, llvm-commits, hiraditya Tags: #llvm Differential Revision: https://reviews.llvm.org/D64228 llvm-svn: 365219
This commit is contained in:
parent
766accd364
commit
fe7ac170a7
|
@ -156,13 +156,19 @@ FileCheckPattern::parseNumericVariableUse(StringRef &Expr,
|
|||
// class instance of the corresponding numeric variable definition is stored
|
||||
// in GlobalNumericVariableTable in parsePattern. Therefore, the pointer we
|
||||
// get below is for the class instance corresponding to the last definition
|
||||
// of this variable use.
|
||||
// of this variable use. If we don't find a variable definition we create a
|
||||
// dummy one so that parsing can continue. All uses of undefined variables,
|
||||
// whether string or numeric, are then diagnosed in printSubstitutions()
|
||||
// after failing to match.
|
||||
auto VarTableIter = Context->GlobalNumericVariableTable.find(Name);
|
||||
if (VarTableIter == Context->GlobalNumericVariableTable.end())
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
SM, Name, "using undefined numeric variable '" + Name + "'");
|
||||
FileCheckNumericVariable *NumericVariable;
|
||||
if (VarTableIter != Context->GlobalNumericVariableTable.end())
|
||||
NumericVariable = VarTableIter->second;
|
||||
else {
|
||||
NumericVariable = Context->makeNumericVariable(0, Name);
|
||||
Context->GlobalNumericVariableTable[Name] = NumericVariable;
|
||||
}
|
||||
|
||||
FileCheckNumericVariable *NumericVariable = VarTableIter->second;
|
||||
if (!IsPseudo && NumericVariable->getDefLineNumber() == LineNumber)
|
||||
return FileCheckErrorDiagnostic::get(
|
||||
SM, Name,
|
||||
|
|
|
@ -76,9 +76,15 @@ UNDEF VAR USE
|
|||
UNDEFVAR: 11
|
||||
UNDEF-USE-LABEL: UNDEF VAR USE
|
||||
UNDEF-USE-NEXT: UNDEFVAR: [[#UNDEFVAR]]
|
||||
UNDEF-USE-MSG: numeric-expression.txt:[[#@LINE-1]]:30: error: using undefined numeric variable 'UNDEFVAR'
|
||||
UNDEF-USE-MSG: numeric-expression.txt:[[#@LINE-1]]:17: error: {{U}}NDEF-USE-NEXT: expected string not found in input
|
||||
UNDEF-USE-MSG-NEXT: {{U}}NDEF-USE-NEXT: UNDEFVAR: {{\[\[#UNDEFVAR\]\]}}
|
||||
UNDEF-USE-MSG-NEXT: {{^ \^$}}
|
||||
UNDEF-USE-MSG-NEXT: {{^ \^$}}
|
||||
UNDEF-USE-MSG-NEXT: numeric-expression.txt:[[#@LINE-6]]:1: note: scanning from here
|
||||
UNDEF-USE-MSG-NEXT: UNDEFVAR: 11
|
||||
UNDEF-USE-MSG-NEXT: {{^\^$}}
|
||||
UNDEF-USE-MSG-NEXT: numeric-expression.txt:[[#@LINE-9]]:1: note: uses undefined variable "UNDEFVAR"
|
||||
UNDEF-USE-MSG-NEXT: UNDEFVAR: 11
|
||||
UNDEF-USE-MSG-NEXT: {{^\^$}}
|
||||
|
||||
; Numeric expression with unsupported operator.
|
||||
RUN: not FileCheck -D#NUMVAR=10 --check-prefix INVAL-OP --input-file %s %s 2>&1 \
|
||||
|
|
|
@ -257,11 +257,11 @@ TEST_F(FileCheckTest, ParseExpr) {
|
|||
// Unacceptable variable.
|
||||
EXPECT_TRUE(Tester.parseSubstExpect("10VAR"));
|
||||
EXPECT_TRUE(Tester.parseSubstExpect("@FOO"));
|
||||
EXPECT_TRUE(Tester.parseSubstExpect("UNDEF"));
|
||||
|
||||
// Only valid variable.
|
||||
EXPECT_FALSE(Tester.parseSubstExpect("@LINE"));
|
||||
EXPECT_FALSE(Tester.parseSubstExpect("FOO"));
|
||||
EXPECT_FALSE(Tester.parseSubstExpect("UNDEF"));
|
||||
|
||||
// Use variable defined on same line.
|
||||
EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:]]"));
|
||||
|
@ -471,9 +471,14 @@ TEST_F(FileCheckTest, FileCheckContext) {
|
|||
P = FileCheckPattern(Check::CheckPlain, &Cxt, 2);
|
||||
Expression = P.parseNumericSubstitutionBlock(LocalNumVarRef,
|
||||
DefinedNumericVariable, SM);
|
||||
EXPECT_TRUE(errorToBool(Expression.takeError()));
|
||||
EXPECT_TRUE(bool(Expression));
|
||||
ExpressionVal = (*Expression)->eval();
|
||||
EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
|
||||
EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
|
||||
EXPECT_TRUE(errorToBool(EmptyVar.takeError()));
|
||||
// Clear again because parseNumericSubstitutionBlock would have created a
|
||||
// dummy variable and stored it in GlobalNumericVariableTable.
|
||||
Cxt.clearLocalVars();
|
||||
|
||||
// Redefine global variables and check variables are defined again.
|
||||
GlobalDefines.emplace_back(std::string("$GlobalVar=BAR"));
|
||||
|
|
Loading…
Reference in New Issue