forked from OSchip/llvm-project
FileCheck [11/12]: Add matching constraint specification
This patch is part of a patch series to add support for FileCheck numeric expressions. This specific patch adds support for specifying the matching constraint for a numeric expression, ie. how the value being matched should relate to the numeric expression. This commit only adds the equality constraint where the numeric value matched must be equal to the numeric expression. It is the default matching constraint used when not specified. It is added to provision other matching constraint (e.g. inequality relations). Copyright: - Linaro (changes up to diff 183612 of revision D55940) - GraphCore (changes in later versions of revision D55940 and in new revision created off D55940) Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D60391
This commit is contained in:
parent
9daccb7a47
commit
47934c7cf9
|
@ -670,7 +670,8 @@ For example:
|
||||||
would match ``mov r5, 0xF0F0`` and set ``REG`` to the value ``5`` and ``IMM``
|
would match ``mov r5, 0xF0F0`` and set ``REG`` to the value ``5`` and ``IMM``
|
||||||
to the value ``0xF0F0``.
|
to the value ``0xF0F0``.
|
||||||
|
|
||||||
The syntax of a numeric substitution is ``[[#%<fmtspec>,<expr>]]`` where:
|
The syntax of a numeric substitution is
|
||||||
|
``[[#%<fmtspec>: <constraint> <expr>]]`` where:
|
||||||
|
|
||||||
* ``%<fmtspec>`` is the same matching format specifier as for defining numeric
|
* ``%<fmtspec>`` is the same matching format specifier as for defining numeric
|
||||||
variables but acting as a printf-style format to indicate how a numeric
|
variables but acting as a printf-style format to indicate how a numeric
|
||||||
|
@ -680,6 +681,12 @@ The syntax of a numeric substitution is ``[[#%<fmtspec>,<expr>]]`` where:
|
||||||
is used. In case of conflict between matching formats of several numeric
|
is used. In case of conflict between matching formats of several numeric
|
||||||
variables the format specifier is mandatory.
|
variables the format specifier is mandatory.
|
||||||
|
|
||||||
|
* ``<constraint>`` is the constraint describing how the value to match must
|
||||||
|
relate to the value of the numeric expression. The only currently accepted
|
||||||
|
constraint is ``==`` for an exact match and is the default if
|
||||||
|
``<constraint>`` is not provided. No matching constraint must be specified
|
||||||
|
when the ``<expr>`` is empty.
|
||||||
|
|
||||||
* ``<expr>`` is an expression. An expression is in turn recursively defined
|
* ``<expr>`` is an expression. An expression is in turn recursively defined
|
||||||
as:
|
as:
|
||||||
|
|
||||||
|
@ -747,11 +754,12 @@ does not matter:
|
||||||
to check that a value is synthesized rather than moved around.
|
to check that a value is synthesized rather than moved around.
|
||||||
|
|
||||||
A numeric variable can also be defined to the result of a numeric expression,
|
A numeric variable can also be defined to the result of a numeric expression,
|
||||||
in which case the numeric expression is checked and if verified the variable is
|
in which case the numeric expression constraint is checked and if verified the
|
||||||
assigned to the value. The unified syntax for both defining numeric variables
|
variable is assigned to the value. The unified syntax for both defining numeric
|
||||||
and checking a numeric expression is thus ``[[#%<fmtspec>,<NUMVAR>: <expr>]]``
|
variables and checking a numeric expression is thus
|
||||||
with each element as described previously. One can use this syntax to make a
|
``[[#%<fmtspec>,<NUMVAR>: <constraint> <expr>]]`` with each element as
|
||||||
testcase more self-describing by using variables instead of values:
|
described previously. One can use this syntax to make a testcase more
|
||||||
|
self-describing by using variables instead of values:
|
||||||
|
|
||||||
.. code-block:: gas
|
.. code-block:: gas
|
||||||
|
|
||||||
|
|
|
@ -448,8 +448,9 @@ Expected<std::unique_ptr<NumericVariableUse>> Pattern::parseNumericVariableUse(
|
||||||
}
|
}
|
||||||
|
|
||||||
Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand(
|
Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand(
|
||||||
StringRef &Expr, AllowedOperand AO, Optional<size_t> LineNumber,
|
StringRef &Expr, AllowedOperand AO, bool MaybeInvalidConstraint,
|
||||||
FileCheckPatternContext *Context, const SourceMgr &SM) {
|
Optional<size_t> LineNumber, FileCheckPatternContext *Context,
|
||||||
|
const SourceMgr &SM) {
|
||||||
if (Expr.startswith("(")) {
|
if (Expr.startswith("(")) {
|
||||||
if (AO != AllowedOperand::Any)
|
if (AO != AllowedOperand::Any)
|
||||||
return ErrorDiagnostic::get(
|
return ErrorDiagnostic::get(
|
||||||
|
@ -497,8 +498,11 @@ Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand(
|
||||||
return std::make_unique<ExpressionLiteral>(SaveExpr.drop_back(Expr.size()),
|
return std::make_unique<ExpressionLiteral>(SaveExpr.drop_back(Expr.size()),
|
||||||
SignedLiteralValue);
|
SignedLiteralValue);
|
||||||
|
|
||||||
return ErrorDiagnostic::get(SM, Expr,
|
return ErrorDiagnostic::get(
|
||||||
"invalid operand format '" + Expr + "'");
|
SM, Expr,
|
||||||
|
Twine("invalid ") +
|
||||||
|
(MaybeInvalidConstraint ? "matching constraint or " : "") +
|
||||||
|
"operand format");
|
||||||
}
|
}
|
||||||
|
|
||||||
Expected<std::unique_ptr<ExpressionAST>>
|
Expected<std::unique_ptr<ExpressionAST>>
|
||||||
|
@ -514,8 +518,9 @@ Pattern::parseParenExpr(StringRef &Expr, Optional<size_t> LineNumber,
|
||||||
return ErrorDiagnostic::get(SM, Expr, "missing operand in expression");
|
return ErrorDiagnostic::get(SM, Expr, "missing operand in expression");
|
||||||
|
|
||||||
// Note: parseNumericOperand handles nested opening parentheses.
|
// Note: parseNumericOperand handles nested opening parentheses.
|
||||||
Expected<std::unique_ptr<ExpressionAST>> SubExprResult =
|
Expected<std::unique_ptr<ExpressionAST>> SubExprResult = parseNumericOperand(
|
||||||
parseNumericOperand(Expr, AllowedOperand::Any, LineNumber, Context, SM);
|
Expr, AllowedOperand::Any, /*MaybeInvalidConstraint=*/false, LineNumber,
|
||||||
|
Context, SM);
|
||||||
Expr = Expr.ltrim(SpaceChars);
|
Expr = Expr.ltrim(SpaceChars);
|
||||||
while (SubExprResult && !Expr.empty() && !Expr.startswith(")")) {
|
while (SubExprResult && !Expr.empty() && !Expr.startswith(")")) {
|
||||||
StringRef OrigExpr = Expr;
|
StringRef OrigExpr = Expr;
|
||||||
|
@ -568,7 +573,8 @@ Pattern::parseBinop(StringRef Expr, StringRef &RemainingExpr,
|
||||||
AllowedOperand AO =
|
AllowedOperand AO =
|
||||||
IsLegacyLineExpr ? AllowedOperand::LegacyLiteral : AllowedOperand::Any;
|
IsLegacyLineExpr ? AllowedOperand::LegacyLiteral : AllowedOperand::Any;
|
||||||
Expected<std::unique_ptr<ExpressionAST>> RightOpResult =
|
Expected<std::unique_ptr<ExpressionAST>> RightOpResult =
|
||||||
parseNumericOperand(RemainingExpr, AO, LineNumber, Context, SM);
|
parseNumericOperand(RemainingExpr, AO, /*MaybeInvalidConstraint=*/false,
|
||||||
|
LineNumber, Context, SM);
|
||||||
if (!RightOpResult)
|
if (!RightOpResult)
|
||||||
return RightOpResult;
|
return RightOpResult;
|
||||||
|
|
||||||
|
@ -606,8 +612,9 @@ Pattern::parseCallExpr(StringRef &Expr, StringRef FuncName,
|
||||||
|
|
||||||
// Parse the argument, which is an arbitary expression.
|
// Parse the argument, which is an arbitary expression.
|
||||||
StringRef OuterBinOpExpr = Expr;
|
StringRef OuterBinOpExpr = Expr;
|
||||||
Expected<std::unique_ptr<ExpressionAST>> Arg =
|
Expected<std::unique_ptr<ExpressionAST>> Arg = parseNumericOperand(
|
||||||
parseNumericOperand(Expr, AllowedOperand::Any, LineNumber, Context, SM);
|
Expr, AllowedOperand::Any, /*MaybeInvalidConstraint=*/false, LineNumber,
|
||||||
|
Context, SM);
|
||||||
while (Arg && !Expr.empty()) {
|
while (Arg && !Expr.empty()) {
|
||||||
Expr = Expr.ltrim(SpaceChars);
|
Expr = Expr.ltrim(SpaceChars);
|
||||||
// Have we reached an argument terminator?
|
// Have we reached an argument terminator?
|
||||||
|
@ -702,17 +709,27 @@ Expected<std::unique_ptr<Expression>> Pattern::parseNumericSubstitutionBlock(
|
||||||
Expr = Expr.substr(DefEnd + 1);
|
Expr = Expr.substr(DefEnd + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse matching constraint.
|
||||||
|
Expr = Expr.ltrim(SpaceChars);
|
||||||
|
bool HasParsedValidConstraint = false;
|
||||||
|
if (Expr.consume_front("=="))
|
||||||
|
HasParsedValidConstraint = true;
|
||||||
|
|
||||||
// Parse the expression itself.
|
// Parse the expression itself.
|
||||||
Expr = Expr.ltrim(SpaceChars);
|
Expr = Expr.ltrim(SpaceChars);
|
||||||
if (!Expr.empty()) {
|
if (Expr.empty()) {
|
||||||
|
if (HasParsedValidConstraint)
|
||||||
|
return ErrorDiagnostic::get(
|
||||||
|
SM, Expr, "empty numeric expression should not have a constraint");
|
||||||
|
} else {
|
||||||
Expr = Expr.rtrim(SpaceChars);
|
Expr = Expr.rtrim(SpaceChars);
|
||||||
StringRef OuterBinOpExpr = Expr;
|
StringRef OuterBinOpExpr = Expr;
|
||||||
// The first operand in a legacy @LINE expression is always the @LINE
|
// The first operand in a legacy @LINE expression is always the @LINE
|
||||||
// pseudo variable.
|
// pseudo variable.
|
||||||
AllowedOperand AO =
|
AllowedOperand AO =
|
||||||
IsLegacyLineExpr ? AllowedOperand::LineVar : AllowedOperand::Any;
|
IsLegacyLineExpr ? AllowedOperand::LineVar : AllowedOperand::Any;
|
||||||
Expected<std::unique_ptr<ExpressionAST>> ParseResult =
|
Expected<std::unique_ptr<ExpressionAST>> ParseResult = parseNumericOperand(
|
||||||
parseNumericOperand(Expr, AO, LineNumber, Context, SM);
|
Expr, AO, !HasParsedValidConstraint, LineNumber, Context, SM);
|
||||||
while (ParseResult && !Expr.empty()) {
|
while (ParseResult && !Expr.empty()) {
|
||||||
ParseResult = parseBinop(OuterBinOpExpr, Expr, std::move(*ParseResult),
|
ParseResult = parseBinop(OuterBinOpExpr, Expr, std::move(*ParseResult),
|
||||||
IsLegacyLineExpr, LineNumber, Context, SM);
|
IsLegacyLineExpr, LineNumber, Context, SM);
|
||||||
|
|
|
@ -728,13 +728,14 @@ private:
|
||||||
/// Parses \p Expr for use of a numeric operand at line \p LineNumber, or
|
/// Parses \p Expr for use of a numeric operand at line \p LineNumber, or
|
||||||
/// before input is parsed if \p LineNumber is None. Accepts literal values,
|
/// before input is parsed if \p LineNumber is None. Accepts literal values,
|
||||||
/// numeric variables and function calls, depending on the value of \p AO.
|
/// numeric variables and function calls, depending on the value of \p AO.
|
||||||
/// Parameter \p Context points to the class instance holding the live string
|
/// \p MaybeInvalidConstraint indicates whether the text being parsed could
|
||||||
/// and numeric variables. \returns the class representing that operand in the
|
/// be an invalid constraint. \p Context points to the class instance holding
|
||||||
/// AST of the expression or an error holding a diagnostic against \p SM
|
/// the live string and numeric variables. \returns the class representing
|
||||||
/// otherwise. If \p Expr starts with a "(" this function will attempt to
|
/// that operand in the AST of the expression or an error holding a
|
||||||
/// parse a parenthesized expression.
|
/// diagnostic against \p SM otherwise. If \p Expr starts with a "(" this
|
||||||
|
/// function will attempt to parse a parenthesized expression.
|
||||||
static Expected<std::unique_ptr<ExpressionAST>>
|
static Expected<std::unique_ptr<ExpressionAST>>
|
||||||
parseNumericOperand(StringRef &Expr, AllowedOperand AO,
|
parseNumericOperand(StringRef &Expr, AllowedOperand AO, bool ConstraintParsed,
|
||||||
Optional<size_t> LineNumber,
|
Optional<size_t> LineNumber,
|
||||||
FileCheckPatternContext *Context, const SourceMgr &SM);
|
FileCheckPatternContext *Context, const SourceMgr &SM);
|
||||||
/// Parses and updates \p RemainingExpr for a binary operation at line
|
/// Parses and updates \p RemainingExpr for a binary operation at line
|
||||||
|
|
|
@ -50,31 +50,33 @@
|
||||||
50 ERR9: line-count.txt:[[#@LINE-1]]:17: error: unsupported operation '*'
|
50 ERR9: line-count.txt:[[#@LINE-1]]:17: error: unsupported operation '*'
|
||||||
51
|
51
|
||||||
52 BAD10: [[@LINE-x]]
|
52 BAD10: [[@LINE-x]]
|
||||||
53 ERR10: line-count.txt:[[#@LINE-1]]:19: error: invalid operand format 'x'
|
53 ERR10: line-count.txt:[[#@LINE-1]]:19: error: invalid operand format
|
||||||
54
|
54 ERR10-NEXT: 52 {{B}}AD10: {{\[\[@LINE-x\]\]}}
|
||||||
55 BAD11: [[@LINE-1x]]
|
55 ERR10-NEXT: {{^}} ^{{$}}
|
||||||
56 ERR11: line-count.txt:[[#@LINE-1]]:20: error: unexpected characters at end of expression 'x'
|
56
|
||||||
57
|
57 BAD11: [[@LINE-1x]]
|
||||||
|
58 ERR11: line-count.txt:[[#@LINE-1]]:20: error: unexpected characters at end of expression 'x'
|
||||||
|
59
|
||||||
; RUN: %ProtectFileCheckOutput \
|
; RUN: %ProtectFileCheckOutput \
|
||||||
; RUN: not FileCheck -check-prefix BAD12 -input-file %s %s 2>&1 \
|
; RUN: not FileCheck -check-prefix BAD12 -input-file %s %s 2>&1 \
|
||||||
; RUN: | FileCheck -check-prefix ERR12 %s
|
; RUN: | FileCheck -check-prefix ERR12 %s
|
||||||
61
|
63
|
||||||
62 BAD12: [[#@LINE-1]] NOT HERE
|
64 BAD12: [[#@LINE-1]] NOT HERE
|
||||||
63 ERR12: note: with "@LINE-1" equal to "61"
|
65 ERR12: note: with "@LINE-1" equal to "63"
|
||||||
64
|
66
|
||||||
; RUN: %ProtectFileCheckOutput \
|
; RUN: %ProtectFileCheckOutput \
|
||||||
; RUN: not FileCheck --check-prefix BAD13 --input-file %s %s 2>&1 \
|
; RUN: not FileCheck --check-prefix BAD13 --input-file %s %s 2>&1 \
|
||||||
; RUN: | FileCheck --check-prefix ERR13 %s
|
; RUN: | FileCheck --check-prefix ERR13 %s
|
||||||
68
|
70
|
||||||
69 BAD13: [[@LINE-0xA]]
|
71 BAD13: [[@LINE-0xA]]
|
||||||
70 ERR13: line-count.txt:[[#@LINE-1]]:20: error: unexpected characters at end of expression 'xA'
|
72 ERR13: line-count.txt:[[#@LINE-1]]:20: error: unexpected characters at end of expression 'xA'
|
||||||
71
|
73
|
||||||
72 CHECK: [[#@LINE]] CHECK
|
|
||||||
73 CHECK: [[# @LINE]] CHECK
|
|
||||||
74 CHECK: [[#@LINE]] CHECK
|
74 CHECK: [[#@LINE]] CHECK
|
||||||
75
|
75 CHECK: [[# @LINE]] CHECK
|
||||||
76 CHECK: [[#@LINE-1]]
|
76 CHECK: [[# @LINE ]] CHECK
|
||||||
77 CHECK: [[# @LINE-1]] CHECK
|
77
|
||||||
78 CHECK: [[# @LINE -1]] CHECK
|
78 CHECK: [[#@LINE-1]]
|
||||||
79 CHECK: [[# @LINE-1]] CHECK
|
79 CHECK: [[# @LINE-1]] CHECK
|
||||||
80 CHECK: [[# @LINE -1]] CHECK
|
80 CHECK: [[# @LINE -1]] CHECK
|
||||||
|
81 CHECK: [[# @LINE - 1]] CHECK
|
||||||
|
82 CHECK: [[# @LINE - 1 ]] CHECK
|
||||||
|
|
|
@ -154,6 +154,54 @@ USE IMPL FMT IMPL MATCH UNSIGNED IMM
|
||||||
CHECK-LABEL: USE IMPL FMT IMPL MATCH UNSIGNED IMM
|
CHECK-LABEL: USE IMPL FMT IMPL MATCH UNSIGNED IMM
|
||||||
CHECK-NEXT: [[#UNSI+0x8000000000000000]]
|
CHECK-NEXT: [[#UNSI+0x8000000000000000]]
|
||||||
|
|
||||||
|
; Numeric expressions in default matching format and explicit matching rule using
|
||||||
|
; variables defined on other lines.
|
||||||
|
USE DEF FMT EXPL MATCH // CHECK-LABEL: USE DEF FMT EXPL MATCH
|
||||||
|
11 // CHECK-NEXT: {{^}}[[#==UNSI]]
|
||||||
|
11 // CHECK-NEXT: {{^}}[[# == UNSI]]
|
||||||
|
12 // CHECK-NEXT: {{^}}[[#UNSI2: == UNSI + 1]]
|
||||||
|
12 // CHECK-NEXT: {{^}}[[#==UNSI2]]
|
||||||
|
|
||||||
|
; Numeric expressions in default matching format and explicit matching rule using
|
||||||
|
; variable defined on other lines with match failure.
|
||||||
|
RUN: %ProtectFileCheckOutput \
|
||||||
|
RUN: not FileCheck --check-prefix NUMEXPR-CONSTRAINT-NOMATCH --input-file %s %s 2>&1 \
|
||||||
|
RUN: | FileCheck --check-prefix NUMEXPR-CONSTRAINT-NOMATCH-MSG --strict-whitespace %s
|
||||||
|
|
||||||
|
USE DEF FMT EXPL NO MATCH
|
||||||
|
12
|
||||||
|
NUMEXPR-CONSTRAINT-NOMATCH-LABEL: USE DEF FMT EXPL NO MATCH
|
||||||
|
NUMEXPR-CONSTRAINT-NOMATCH-NEXT: [[#==UNSI]]
|
||||||
|
NUMEXPR-CONSTRAINT-NOMATCH-MSG: numeric-expression.txt:[[#@LINE-1]]:34: error: {{N}}UMEXPR-CONSTRAINT-NOMATCH-NEXT: expected string not found in input
|
||||||
|
NUMEXPR-CONSTRAINT-NOMATCH-MSG-NEXT: {{N}}UMEXPR-CONSTRAINT-NOMATCH-NEXT: {{\[\[#==UNSI\]\]}}
|
||||||
|
NUMEXPR-CONSTRAINT-NOMATCH-MSG-NEXT: {{^}} ^{{$}}
|
||||||
|
|
||||||
|
; Empty numeric expression with matching constraint.
|
||||||
|
RUN: %ProtectFileCheckOutput \
|
||||||
|
RUN: not FileCheck --check-prefix EMPTY-NUMEXPR-CONSTRAINT --input-file %s %s 2>&1 \
|
||||||
|
RUN: | FileCheck --check-prefix EMPTY-NUMEXPR-CONSTRAINT-MSG --strict-whitespace %s
|
||||||
|
|
||||||
|
EMPTY NUMEXPR USE WITH CONSTRAINT
|
||||||
|
18
|
||||||
|
EMPTY-NUMEXPR-CONSTRAINT-LABEL: EMPTY NUMEXPR USE WITH CONSTRAINT
|
||||||
|
EMPTY-NUMEXPR-CONSTRAINT-NEXT: [[# ==]]
|
||||||
|
EMPTY-NUMEXPR-CONSTRAINT-MSG: numeric-expression.txt:[[#@LINE-1]]:38: error: empty numeric expression should not have a constraint
|
||||||
|
EMPTY-NUMEXPR-CONSTRAINT-MSG-NEXT: {{E}}MPTY-NUMEXPR-CONSTRAINT-NEXT: {{\[\[# ==\]\]}}
|
||||||
|
EMPTY-NUMEXPR-CONSTRAINT-MSG-NEXT: {{^}} ^{{$}}
|
||||||
|
|
||||||
|
; Definition from empty numeric expression with matching constraint.
|
||||||
|
RUN: %ProtectFileCheckOutput \
|
||||||
|
RUN: not FileCheck --check-prefix EMPTY-NUMDEF-CONSTRAINT --input-file %s %s 2>&1 \
|
||||||
|
RUN: | FileCheck --check-prefix EMPTY-NUMDEF-CONSTRAINT-MSG %s
|
||||||
|
|
||||||
|
EMPTY NUMEXPR DEF WITH CONSTRAINT
|
||||||
|
18
|
||||||
|
EMPTY-NUMDEF-CONSTRAINT-LABEL: EMPTY NUMEXPR CONSTRAINT
|
||||||
|
EMPTY-NUMDEF-CONSTRAINT-NEXT: [[#VARDEF: ==]]
|
||||||
|
EMPTY-NUMDEF-CONSTRAINT-MSG: numeric-expression.txt:[[#@LINE-1]]:44: error: empty numeric expression should not have a constraint
|
||||||
|
EMPTY-NUMDEF-CONSTRAINT-MSG-NEXT: {{E}}MPTY-NUMDEF-CONSTRAINT-NEXT: {{\[\[#VARDEF: ==\]\]}}
|
||||||
|
EMPTY-NUMDEF-CONSTRAINT-MSG-NEXT: {{^}} ^{{$}}
|
||||||
|
|
||||||
; Numeric expressions with matching format overriding the implicit format of
|
; Numeric expressions with matching format overriding the implicit format of
|
||||||
; variables defined on other lines.
|
; variables defined on other lines.
|
||||||
USE CONV FMT IMPL MATCH // CHECK-LABEL: USE CONV FMT IMPL MATCH
|
USE CONV FMT IMPL MATCH // CHECK-LABEL: USE CONV FMT IMPL MATCH
|
||||||
|
|
|
@ -902,7 +902,7 @@ TEST_F(FileCheckTest, ParseNumericSubstitutionBlock) {
|
||||||
Tester.initNextPattern();
|
Tester.initNextPattern();
|
||||||
|
|
||||||
// Invalid variable name.
|
// Invalid variable name.
|
||||||
expectDiagnosticError("invalid operand format '%VAR'",
|
expectDiagnosticError("invalid matching constraint or operand format",
|
||||||
Tester.parseSubst("%VAR").takeError());
|
Tester.parseSubst("%VAR").takeError());
|
||||||
|
|
||||||
expectDiagnosticError("invalid pseudo numeric variable '@FOO'",
|
expectDiagnosticError("invalid pseudo numeric variable '@FOO'",
|
||||||
|
@ -937,6 +937,10 @@ TEST_F(FileCheckTest, ParseNumericSubstitutionBlock) {
|
||||||
// Valid empty expression.
|
// Valid empty expression.
|
||||||
EXPECT_THAT_EXPECTED(Tester.parseSubst(""), Succeeded());
|
EXPECT_THAT_EXPECTED(Tester.parseSubst(""), Succeeded());
|
||||||
|
|
||||||
|
// Invalid equality matching constraint with empty expression.
|
||||||
|
expectDiagnosticError("empty numeric expression should not have a constraint",
|
||||||
|
Tester.parseSubst("==").takeError());
|
||||||
|
|
||||||
// Valid single operand expression.
|
// Valid single operand expression.
|
||||||
EXPECT_THAT_EXPECTED(Tester.parseSubst("FOO"), Succeeded());
|
EXPECT_THAT_EXPECTED(Tester.parseSubst("FOO"), Succeeded());
|
||||||
EXPECT_THAT_EXPECTED(Tester.parseSubst("18"), Succeeded());
|
EXPECT_THAT_EXPECTED(Tester.parseSubst("18"), Succeeded());
|
||||||
|
@ -947,6 +951,13 @@ TEST_F(FileCheckTest, ParseNumericSubstitutionBlock) {
|
||||||
EXPECT_THAT_EXPECTED(Tester.parseSubst(std::to_string(MinInt64)),
|
EXPECT_THAT_EXPECTED(Tester.parseSubst(std::to_string(MinInt64)),
|
||||||
Succeeded());
|
Succeeded());
|
||||||
|
|
||||||
|
// Valid optional matching constraint.
|
||||||
|
EXPECT_THAT_EXPECTED(Tester.parseSubst("==FOO"), Succeeded());
|
||||||
|
|
||||||
|
// Invalid matching constraint.
|
||||||
|
expectDiagnosticError("invalid matching constraint or operand format",
|
||||||
|
Tester.parseSubst("+=FOO").takeError());
|
||||||
|
|
||||||
// Invalid format.
|
// Invalid format.
|
||||||
expectDiagnosticError("invalid matching format specification in expression",
|
expectDiagnosticError("invalid matching format specification in expression",
|
||||||
Tester.parseSubst("X,FOO:").takeError());
|
Tester.parseSubst("X,FOO:").takeError());
|
||||||
|
@ -968,12 +979,12 @@ TEST_F(FileCheckTest, ParseNumericSubstitutionBlock) {
|
||||||
|
|
||||||
// Errors in RHS operand are bubbled up by parseBinop() to
|
// Errors in RHS operand are bubbled up by parseBinop() to
|
||||||
// parseNumericSubstitutionBlock().
|
// parseNumericSubstitutionBlock().
|
||||||
expectDiagnosticError("invalid operand format '%VAR'",
|
expectDiagnosticError("invalid operand format",
|
||||||
Tester.parseSubst("@LINE+%VAR").takeError());
|
Tester.parseSubst("@LINE+%VAR").takeError());
|
||||||
|
|
||||||
// Invalid legacy @LINE expression with non literal rhs.
|
// Invalid legacy @LINE expression with non literal rhs.
|
||||||
expectDiagnosticError(
|
expectDiagnosticError(
|
||||||
"invalid operand format '@LINE'",
|
"invalid operand format",
|
||||||
Tester.parseSubst("@LINE+@LINE", /*IsLegacyNumExpr=*/true).takeError());
|
Tester.parseSubst("@LINE+@LINE", /*IsLegacyNumExpr=*/true).takeError());
|
||||||
|
|
||||||
// Invalid legacy @LINE expression made of a single literal.
|
// Invalid legacy @LINE expression made of a single literal.
|
||||||
|
@ -1046,7 +1057,7 @@ TEST_F(FileCheckTest, ParseNumericSubstitutionBlock) {
|
||||||
|
|
||||||
// Test more closing than opening parentheses. The diagnostic messages are
|
// Test more closing than opening parentheses. The diagnostic messages are
|
||||||
// not ideal, but for now simply check that we reject invalid input.
|
// not ideal, but for now simply check that we reject invalid input.
|
||||||
expectDiagnosticError("invalid operand format ')'",
|
expectDiagnosticError("invalid matching constraint or operand format",
|
||||||
Tester.parseSubst(")").takeError());
|
Tester.parseSubst(")").takeError());
|
||||||
expectDiagnosticError("unsupported operation ')'",
|
expectDiagnosticError("unsupported operation ')'",
|
||||||
Tester.parseSubst("1)").takeError());
|
Tester.parseSubst("1)").takeError());
|
||||||
|
|
Loading…
Reference in New Issue