llvm.org GIT mirror llvm / b8590ea
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365219 91177308-0d34-0410-b5e6-96231b3b80d8 Thomas Preud'homme 3 months ago
3 changed file(s) with 27 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
155155 // class instance of the corresponding numeric variable definition is stored
156156 // in GlobalNumericVariableTable in parsePattern. Therefore, the pointer we
157157 // get below is for the class instance corresponding to the last definition
158 // of this variable use.
158 // of this variable use. If we don't find a variable definition we create a
159 // dummy one so that parsing can continue. All uses of undefined variables,
160 // whether string or numeric, are then diagnosed in printSubstitutions()
161 // after failing to match.
159162 auto VarTableIter = Context->GlobalNumericVariableTable.find(Name);
160 if (VarTableIter == Context->GlobalNumericVariableTable.end())
161 return FileCheckErrorDiagnostic::get(
162 SM, Name, "using undefined numeric variable '" + Name + "'");
163
164 FileCheckNumericVariable *NumericVariable = VarTableIter->second;
163 FileCheckNumericVariable *NumericVariable;
164 if (VarTableIter != Context->GlobalNumericVariableTable.end())
165 NumericVariable = VarTableIter->second;
166 else {
167 NumericVariable = Context->makeNumericVariable(0, Name);
168 Context->GlobalNumericVariableTable[Name] = NumericVariable;
169 }
170
165171 if (!IsPseudo && NumericVariable->getDefLineNumber() == LineNumber)
166172 return FileCheckErrorDiagnostic::get(
167173 SM, Name,
7575 UNDEFVAR: 11
7676 UNDEF-USE-LABEL: UNDEF VAR USE
7777 UNDEF-USE-NEXT: UNDEFVAR: [[#UNDEFVAR]]
78 UNDEF-USE-MSG: numeric-expression.txt:[[#@LINE-1]]:30: error: using undefined numeric variable 'UNDEFVAR'
78 UNDEF-USE-MSG: numeric-expression.txt:[[#@LINE-1]]:17: error: {{U}}NDEF-USE-NEXT: expected string not found in input
7979 UNDEF-USE-MSG-NEXT: {{U}}NDEF-USE-NEXT: UNDEFVAR: {{\[\[#UNDEFVAR\]\]}}
80 UNDEF-USE-MSG-NEXT: {{^ \^$}}
80 UNDEF-USE-MSG-NEXT: {{^ \^$}}
81 UNDEF-USE-MSG-NEXT: numeric-expression.txt:[[#@LINE-6]]:1: note: scanning from here
82 UNDEF-USE-MSG-NEXT: UNDEFVAR: 11
83 UNDEF-USE-MSG-NEXT: {{^\^$}}
84 UNDEF-USE-MSG-NEXT: numeric-expression.txt:[[#@LINE-9]]:1: note: uses undefined variable "UNDEFVAR"
85 UNDEF-USE-MSG-NEXT: UNDEFVAR: 11
86 UNDEF-USE-MSG-NEXT: {{^\^$}}
8187
8288 ; Numeric expression with unsupported operator.
8389 RUN: not FileCheck -D#NUMVAR=10 --check-prefix INVAL-OP --input-file %s %s 2>&1 \
256256 // Unacceptable variable.
257257 EXPECT_TRUE(Tester.parseSubstExpect("10VAR"));
258258 EXPECT_TRUE(Tester.parseSubstExpect("@FOO"));
259 EXPECT_TRUE(Tester.parseSubstExpect("UNDEF"));
260259
261260 // Only valid variable.
262261 EXPECT_FALSE(Tester.parseSubstExpect("@LINE"));
263262 EXPECT_FALSE(Tester.parseSubstExpect("FOO"));
263 EXPECT_FALSE(Tester.parseSubstExpect("UNDEF"));
264264
265265 // Use variable defined on same line.
266266 EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:]]"));
470470 P = FileCheckPattern(Check::CheckPlain, &Cxt, 2);
471471 Expression = P.parseNumericSubstitutionBlock(LocalNumVarRef,
472472 DefinedNumericVariable, SM);
473 EXPECT_TRUE(errorToBool(Expression.takeError()));
473 EXPECT_TRUE(bool(Expression));
474 ExpressionVal = (*Expression)->eval();
475 EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
474476 EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
475477 EXPECT_TRUE(errorToBool(EmptyVar.takeError()));
478 // Clear again because parseNumericSubstitutionBlock would have created a
479 // dummy variable and stored it in GlobalNumericVariableTable.
480 Cxt.clearLocalVars();
476481
477482 // Redefine global variables and check variables are defined again.
478483 GlobalDefines.emplace_back(std::string("$GlobalVar=BAR"));