[PATCH] D64228: [FileCheck] Don't diagnose undef vars at parse time

Thomas Preud'homme via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 4 16:51:03 PDT 2019


thopre created this revision.
thopre added reviewers: jhenderson, chandlerc, jdenny, probinson, grimar, arichardson, rnk.
thopre added a project: LLVM.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D64228

Files:
  llvm/lib/Support/FileCheck.cpp
  llvm/test/FileCheck/numeric-expression.txt
  llvm/unittests/Support/FileCheckTest.cpp


Index: llvm/unittests/Support/FileCheckTest.cpp
===================================================================
--- llvm/unittests/Support/FileCheckTest.cpp
+++ llvm/unittests/Support/FileCheckTest.cpp
@@ -257,11 +257,11 @@
   // 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 @@
   P = FileCheckPattern(Check::CheckPlain, &Cxt, 2);
   Expression = P.parseNumericSubstitutionBlock(LocalNumVarRef,
                                                DefinedNumericVariable, SM);
-  EXPECT_TRUE(errorToBool(Expression.takeError()));
+  EXPECT_TRUE(static_cast<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 store it in GlobalNumericVariableTable.
+  Cxt.clearLocalVars();
 
   // Redefine global variables and check variables are defined again.
   GlobalDefines.emplace_back(std::string("$GlobalVar=BAR"));
Index: llvm/test/FileCheck/numeric-expression.txt
===================================================================
--- llvm/test/FileCheck/numeric-expression.txt
+++ llvm/test/FileCheck/numeric-expression.txt
@@ -69,16 +69,12 @@
 CHECK-NEXT: [[#VAR1+9223372036854775808]]
 
 ; Numeric expression using undefined variable.
-RUN: not FileCheck --check-prefix UNDEF-USE --input-file %s %s 2>&1 \
-RUN:   | FileCheck --strict-whitespace --check-prefix UNDEF-USE-MSG %s
+RUN: not FileCheck --check-prefix UNDEF-USE --input-file %s %s
 
 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-NEXT: {{U}}NDEF-USE-NEXT: UNDEFVAR: {{\[\[#UNDEFVAR\]\]}}
-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 \
Index: llvm/lib/Support/FileCheck.cpp
===================================================================
--- llvm/lib/Support/FileCheck.cpp
+++ llvm/lib/Support/FileCheck.cpp
@@ -156,13 +156,19 @@
   // 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 use of undefined variables,
+  // whether string or numeric, are then diagnosed when 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,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D64228.208095.patch
Type: text/x-patch
Size: 4001 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190704/6635cbf1/attachment.bin>


More information about the llvm-commits mailing list