forked from OSchip/llvm-project
[clang-tidy] Reject invalid enum initializers in C files
C requires that enum values fit into an int. Scan the macro tokens present in an initializing expression and reject macros that contain tokens that have suffixes making them larger than int. C forbids the comma operator in enum initializing expressions, so optionally reject comma operator. Differential Revision: https://reviews.llvm.org/D125622 Fixes #55467
This commit is contained in:
parent
6eab5cade7
commit
b418ef5cb9
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "IntegralLiteralExpressionMatcher.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <stdexcept>
|
||||
|
||||
|
@ -81,6 +82,50 @@ bool IntegralLiteralExpressionMatcher::unaryOperator() {
|
|||
return true;
|
||||
}
|
||||
|
||||
static LiteralSize literalTokenSize(const Token &Tok) {
|
||||
unsigned int Length = Tok.getLength();
|
||||
if (Length <= 1)
|
||||
return LiteralSize::Int;
|
||||
|
||||
bool SeenUnsigned = false;
|
||||
bool SeenLong = false;
|
||||
bool SeenLongLong = false;
|
||||
const char *Text = Tok.getLiteralData();
|
||||
for (unsigned int End = Length - 1; End > 0; --End) {
|
||||
if (std::isdigit(Text[End]))
|
||||
break;
|
||||
|
||||
if (std::toupper(Text[End]) == 'U')
|
||||
SeenUnsigned = true;
|
||||
else if (std::toupper(Text[End]) == 'L') {
|
||||
if (SeenLong)
|
||||
SeenLongLong = true;
|
||||
SeenLong = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (SeenLongLong) {
|
||||
if (SeenUnsigned)
|
||||
return LiteralSize::UnsignedLongLong;
|
||||
|
||||
return LiteralSize::LongLong;
|
||||
}
|
||||
if (SeenLong) {
|
||||
if (SeenUnsigned)
|
||||
return LiteralSize::UnsignedLong;
|
||||
|
||||
return LiteralSize::Long;
|
||||
}
|
||||
if (SeenUnsigned)
|
||||
return LiteralSize::UnsignedInt;
|
||||
|
||||
return LiteralSize::Int;
|
||||
}
|
||||
|
||||
static bool operator<(LiteralSize LHS, LiteralSize RHS) {
|
||||
return static_cast<int>(LHS) < static_cast<int>(RHS);
|
||||
}
|
||||
|
||||
bool IntegralLiteralExpressionMatcher::unaryExpr() {
|
||||
if (!unaryOperator())
|
||||
return false;
|
||||
|
@ -102,7 +147,10 @@ bool IntegralLiteralExpressionMatcher::unaryExpr() {
|
|||
!isIntegralConstant(*Current)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LargestSize = std::max(LargestSize, literalTokenSize(*Current));
|
||||
++Current;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -217,14 +265,24 @@ bool IntegralLiteralExpressionMatcher::conditionalExpr() {
|
|||
}
|
||||
|
||||
bool IntegralLiteralExpressionMatcher::commaExpr() {
|
||||
return nonTerminalChainedExpr<tok::TokenKind::comma>(
|
||||
&IntegralLiteralExpressionMatcher::conditionalExpr);
|
||||
auto Pred = CommaAllowed
|
||||
? std::function<bool(Token)>(
|
||||
[](Token Tok) { return Tok.is(tok::TokenKind::comma); })
|
||||
: std::function<bool(Token)>([](Token) { return false; });
|
||||
return nonTerminalChainedExpr(
|
||||
&IntegralLiteralExpressionMatcher::conditionalExpr, Pred);
|
||||
}
|
||||
|
||||
bool IntegralLiteralExpressionMatcher::expr() { return commaExpr(); }
|
||||
|
||||
bool IntegralLiteralExpressionMatcher::match() {
|
||||
return expr() && Current == End;
|
||||
// Top-level allowed expression is conditionalExpr(), not expr(), because
|
||||
// comma operators are only valid initializers when used inside parentheses.
|
||||
return conditionalExpr() && Current == End;
|
||||
}
|
||||
|
||||
LiteralSize IntegralLiteralExpressionMatcher::largestLiteralSize() const {
|
||||
return LargestSize;
|
||||
}
|
||||
|
||||
} // namespace modernize
|
||||
|
|
|
@ -16,15 +16,27 @@ namespace clang {
|
|||
namespace tidy {
|
||||
namespace modernize {
|
||||
|
||||
enum class LiteralSize {
|
||||
Unknown = 0,
|
||||
Int,
|
||||
UnsignedInt,
|
||||
Long,
|
||||
UnsignedLong,
|
||||
LongLong,
|
||||
UnsignedLongLong
|
||||
};
|
||||
|
||||
// Parses an array of tokens and returns true if they conform to the rules of
|
||||
// C++ for whole expressions involving integral literals. Follows the operator
|
||||
// precedence rules of C++.
|
||||
// precedence rules of C++. Optionally exclude comma operator expressions.
|
||||
class IntegralLiteralExpressionMatcher {
|
||||
public:
|
||||
IntegralLiteralExpressionMatcher(ArrayRef<Token> Tokens)
|
||||
: Current(Tokens.begin()), End(Tokens.end()) {}
|
||||
IntegralLiteralExpressionMatcher(ArrayRef<Token> Tokens, bool CommaAllowed)
|
||||
: Current(Tokens.begin()), End(Tokens.end()), CommaAllowed(CommaAllowed) {
|
||||
}
|
||||
|
||||
bool match();
|
||||
LiteralSize largestLiteralSize() const;
|
||||
|
||||
private:
|
||||
bool advance();
|
||||
|
@ -64,6 +76,8 @@ private:
|
|||
|
||||
ArrayRef<Token>::iterator Current;
|
||||
ArrayRef<Token>::iterator End;
|
||||
LiteralSize LargestSize{LiteralSize::Unknown};
|
||||
bool CommaAllowed;
|
||||
};
|
||||
|
||||
} // namespace modernize
|
||||
|
|
|
@ -321,8 +321,14 @@ void MacroToEnumCallbacks::FileChanged(SourceLocation Loc,
|
|||
|
||||
bool MacroToEnumCallbacks::isInitializer(ArrayRef<Token> MacroTokens)
|
||||
{
|
||||
IntegralLiteralExpressionMatcher Matcher(MacroTokens);
|
||||
return Matcher.match();
|
||||
IntegralLiteralExpressionMatcher Matcher(MacroTokens, LangOpts.C99 == 0);
|
||||
bool Matched = Matcher.match();
|
||||
bool isC = !LangOpts.CPlusPlus;
|
||||
if (isC && (Matcher.largestLiteralSize() != LiteralSize::Int &&
|
||||
Matcher.largestLiteralSize() != LiteralSize::UnsignedInt))
|
||||
return false;
|
||||
|
||||
return Matched;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// RUN: %check_clang_tidy %s modernize-macro-to-enum %t
|
||||
|
||||
// C requires enum values to fit into an int.
|
||||
#define TOO_BIG1 1L
|
||||
#define TOO_BIG2 1UL
|
||||
#define TOO_BIG3 1LL
|
||||
#define TOO_BIG4 1ULL
|
||||
|
||||
// C forbids comma operator in initializing expressions.
|
||||
#define BAD_OP 1, 2
|
||||
|
||||
#define SIZE_OK1 1
|
||||
#define SIZE_OK2 1U
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: replace macro with enum [modernize-macro-to-enum]
|
||||
// CHECK-MESSAGES: :[[@LINE-3]]:9: warning: macro 'SIZE_OK1' defines an integral constant; prefer an enum instead
|
||||
// CHECK-MESSAGES: :[[@LINE-3]]:9: warning: macro 'SIZE_OK2' defines an integral constant; prefer an enum instead
|
|
@ -213,6 +213,13 @@
|
|||
// CHECK-FIXES-NEXT: COMPLEX_PAREN6 = ((+1))
|
||||
// CHECK-FIXES-NEXT: };
|
||||
|
||||
#define GOOD_COMMA (1, 2)
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: replace macro with enum
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: macro 'GOOD_COMMA' defines an integral constant; prefer an enum instead
|
||||
// CHECK-FIXES: enum {
|
||||
// CHECK-FIXES-NEXT: GOOD_COMMA = (1, 2)
|
||||
// CHECK-FIXES-NEXT: };
|
||||
|
||||
// Macros appearing in conditional expressions can't be replaced
|
||||
// by enums.
|
||||
#define USE_FOO 1
|
||||
|
@ -322,6 +329,9 @@ inline void used_ifndef() {}
|
|||
#define EPS2 1e5
|
||||
#define EPS3 1.
|
||||
|
||||
// Ignore macros invoking comma operator unless they are inside parens.
|
||||
#define BAD_COMMA 1, 2
|
||||
|
||||
extern void draw(unsigned int Color);
|
||||
|
||||
void f()
|
||||
|
|
|
@ -36,177 +36,241 @@ static std::vector<Token> tokenify(const char *Text) {
|
|||
return Tokens;
|
||||
}
|
||||
|
||||
static bool matchText(const char *Text) {
|
||||
static bool matchText(const char *Text, bool AllowComma) {
|
||||
std::vector<Token> Tokens{tokenify(Text)};
|
||||
modernize::IntegralLiteralExpressionMatcher Matcher(Tokens);
|
||||
modernize::IntegralLiteralExpressionMatcher Matcher(Tokens, AllowComma);
|
||||
|
||||
return Matcher.match();
|
||||
}
|
||||
|
||||
static modernize::LiteralSize sizeText(const char *Text) {
|
||||
std::vector<Token> Tokens{tokenify(Text)};
|
||||
modernize::IntegralLiteralExpressionMatcher Matcher(Tokens, true);
|
||||
if (Matcher.match())
|
||||
return Matcher.largestLiteralSize();
|
||||
return modernize::LiteralSize::Unknown;
|
||||
}
|
||||
|
||||
static const char *toString(modernize::LiteralSize Value) {
|
||||
switch (Value) {
|
||||
case modernize::LiteralSize::Int:
|
||||
return "Int";
|
||||
case modernize::LiteralSize::UnsignedInt:
|
||||
return "UnsignedInt";
|
||||
case modernize::LiteralSize::Long:
|
||||
return "Long";
|
||||
case modernize::LiteralSize::UnsignedLong:
|
||||
return "UnsignedLong";
|
||||
case modernize::LiteralSize::LongLong:
|
||||
return "LongLong";
|
||||
case modernize::LiteralSize::UnsignedLongLong:
|
||||
return "UnsignedLongLong";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct Param {
|
||||
struct MatchParam {
|
||||
bool AllowComma;
|
||||
bool Matched;
|
||||
const char *Text;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &Str, const Param &Value) {
|
||||
return Str << "Matched: " << std::boolalpha << Value.Matched << ", Text: '"
|
||||
<< Value.Text << "'";
|
||||
friend std::ostream &operator<<(std::ostream &Str, const MatchParam &Value) {
|
||||
return Str << "Allow operator,: " << std::boolalpha << Value.AllowComma
|
||||
<< ", Matched: " << std::boolalpha << Value.Matched
|
||||
<< ", Text: '" << Value.Text << '\'';
|
||||
}
|
||||
};
|
||||
|
||||
class MatcherTest : public ::testing::TestWithParam<Param> {};
|
||||
struct SizeParam {
|
||||
modernize::LiteralSize Size;
|
||||
const char *Text;
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &Str, const SizeParam &Value) {
|
||||
return Str << "Size: " << toString(Value.Size) << ", Text: '" << Value.Text << '\'';
|
||||
}
|
||||
};
|
||||
|
||||
class MatcherTest : public ::testing::TestWithParam<MatchParam> {};
|
||||
|
||||
class SizeTest : public ::testing::TestWithParam<SizeParam> {};
|
||||
|
||||
} // namespace
|
||||
|
||||
static const Param Params[] = {
|
||||
static const MatchParam MatchParams[] = {
|
||||
// Accept integral literals.
|
||||
{true, "1"},
|
||||
{true, "0177"},
|
||||
{true, "0xdeadbeef"},
|
||||
{true, "0b1011"},
|
||||
{true, "'c'"},
|
||||
{true, true, "1"},
|
||||
{true, true, "0177"},
|
||||
{true, true, "0xdeadbeef"},
|
||||
{true, true, "0b1011"},
|
||||
{true, true, "'c'"},
|
||||
// Reject non-integral literals.
|
||||
{false, "1.23"},
|
||||
{false, "0x1p3"},
|
||||
{false, R"("string")"},
|
||||
{false, "1i"},
|
||||
{true, false, "1.23"},
|
||||
{true, false, "0x1p3"},
|
||||
{true, false, R"("string")"},
|
||||
{true, false, "1i"},
|
||||
|
||||
// Accept literals with these unary operators.
|
||||
{true, "-1"},
|
||||
{true, "+1"},
|
||||
{true, "~1"},
|
||||
{true, "!1"},
|
||||
{true, true, "-1"},
|
||||
{true, true, "+1"},
|
||||
{true, true, "~1"},
|
||||
{true, true, "!1"},
|
||||
// Reject invalid unary operators.
|
||||
{false, "1-"},
|
||||
{false, "1+"},
|
||||
{false, "1~"},
|
||||
{false, "1!"},
|
||||
{true, false, "1-"},
|
||||
{true, false, "1+"},
|
||||
{true, false, "1~"},
|
||||
{true, false, "1!"},
|
||||
|
||||
// Accept valid binary operators.
|
||||
{true, "1+1"},
|
||||
{true, "1-1"},
|
||||
{true, "1*1"},
|
||||
{true, "1/1"},
|
||||
{true, "1%2"},
|
||||
{true, "1<<1"},
|
||||
{true, "1>>1"},
|
||||
{true, "1<=>1"},
|
||||
{true, "1<1"},
|
||||
{true, "1>1"},
|
||||
{true, "1<=1"},
|
||||
{true, "1>=1"},
|
||||
{true, "1==1"},
|
||||
{true, "1!=1"},
|
||||
{true, "1&1"},
|
||||
{true, "1^1"},
|
||||
{true, "1|1"},
|
||||
{true, "1&&1"},
|
||||
{true, "1||1"},
|
||||
{true, "1+ +1"}, // A space is needed to avoid being tokenized as ++ or --.
|
||||
{true, "1- -1"},
|
||||
{true, "1,1"},
|
||||
{true, true, "1+1"},
|
||||
{true, true, "1-1"},
|
||||
{true, true, "1*1"},
|
||||
{true, true, "1/1"},
|
||||
{true, true, "1%2"},
|
||||
{true, true, "1<<1"},
|
||||
{true, true, "1>>1"},
|
||||
{true, true, "1<=>1"},
|
||||
{true, true, "1<1"},
|
||||
{true, true, "1>1"},
|
||||
{true, true, "1<=1"},
|
||||
{true, true, "1>=1"},
|
||||
{true, true, "1==1"},
|
||||
{true, true, "1!=1"},
|
||||
{true, true, "1&1"},
|
||||
{true, true, "1^1"},
|
||||
{true, true, "1|1"},
|
||||
{true, true, "1&&1"},
|
||||
{true, true, "1||1"},
|
||||
{true, true, "1+ +1"}, // A space is needed to avoid being tokenized as ++ or --.
|
||||
{true, true, "1- -1"},
|
||||
// Comma is only valid when inside parentheses.
|
||||
{true, true, "(1,1)"},
|
||||
// Reject invalid binary operators.
|
||||
{false, "1+"},
|
||||
{false, "1-"},
|
||||
{false, "1*"},
|
||||
{false, "1/"},
|
||||
{false, "1%"},
|
||||
{false, "1<<"},
|
||||
{false, "1>>"},
|
||||
{false, "1<=>"},
|
||||
{false, "1<"},
|
||||
{false, "1>"},
|
||||
{false, "1<="},
|
||||
{false, "1>="},
|
||||
{false, "1=="},
|
||||
{false, "1!="},
|
||||
{false, "1&"},
|
||||
{false, "1^"},
|
||||
{false, "1|"},
|
||||
{false, "1&&"},
|
||||
{false, "1||"},
|
||||
{false, "1,"},
|
||||
{false, ",1"},
|
||||
{true, false, "1+"},
|
||||
{true, false, "1-"},
|
||||
{true, false, "1*"},
|
||||
{true, false, "1/"},
|
||||
{true, false, "1%"},
|
||||
{true, false, "1<<"},
|
||||
{true, false, "1>>"},
|
||||
{true, false, "1<=>"},
|
||||
{true, false, "1<"},
|
||||
{true, false, "1>"},
|
||||
{true, false, "1<="},
|
||||
{true, false, "1>="},
|
||||
{true, false, "1=="},
|
||||
{true, false, "1!="},
|
||||
{true, false, "1&"},
|
||||
{true, false, "1^"},
|
||||
{true, false, "1|"},
|
||||
{true, false, "1&&"},
|
||||
{true, false, "1||"},
|
||||
{true, false, "1,"},
|
||||
{true, false, ",1"},
|
||||
{true, false, "1,1"},
|
||||
|
||||
// Accept valid ternary operators.
|
||||
{true, "1?1:1"},
|
||||
{true, "1?:1"}, // A gcc extension treats x ? : y as x ? x : y.
|
||||
{true, true, "1?1:1"},
|
||||
{true, true, "1?:1"}, // A gcc extension treats x ? : y as x ? x : y.
|
||||
// Reject invalid ternary operators.
|
||||
{false, "?"},
|
||||
{false, "?1"},
|
||||
{false, "?:"},
|
||||
{false, "?:1"},
|
||||
{false, "?1:"},
|
||||
{false, "?1:1"},
|
||||
{false, "1?"},
|
||||
{false, "1?1"},
|
||||
{false, "1?:"},
|
||||
{false, "1?1:"},
|
||||
{true, false, "?"},
|
||||
{true, false, "?1"},
|
||||
{true, false, "?:"},
|
||||
{true, false, "?:1"},
|
||||
{true, false, "?1:"},
|
||||
{true, false, "?1:1"},
|
||||
{true, false, "1?"},
|
||||
{true, false, "1?1"},
|
||||
{true, false, "1?:"},
|
||||
{true, false, "1?1:"},
|
||||
|
||||
// Accept parenthesized expressions.
|
||||
{true, "(1)"},
|
||||
{true, "((+1))"},
|
||||
{true, "((+(1)))"},
|
||||
{true, "(-1)"},
|
||||
{true, "-(1)"},
|
||||
{true, "(+1)"},
|
||||
{true, "((+1))"},
|
||||
{true, "+(1)"},
|
||||
{true, "(~1)"},
|
||||
{true, "~(1)"},
|
||||
{true, "(!1)"},
|
||||
{true, "!(1)"},
|
||||
{true, "(1+1)"},
|
||||
{true, "(1-1)"},
|
||||
{true, "(1*1)"},
|
||||
{true, "(1/1)"},
|
||||
{true, "(1%2)"},
|
||||
{true, "(1<<1)"},
|
||||
{true, "(1>>1)"},
|
||||
{true, "(1<=>1)"},
|
||||
{true, "(1<1)"},
|
||||
{true, "(1>1)"},
|
||||
{true, "(1<=1)"},
|
||||
{true, "(1>=1)"},
|
||||
{true, "(1==1)"},
|
||||
{true, "(1!=1)"},
|
||||
{true, "(1&1)"},
|
||||
{true, "(1^1)"},
|
||||
{true, "(1|1)"},
|
||||
{true, "(1&&1)"},
|
||||
{true, "(1||1)"},
|
||||
{true, "(1?1:1)"},
|
||||
{true, true, "(1)"},
|
||||
{true, true, "((+1))"},
|
||||
{true, true, "((+(1)))"},
|
||||
{true, true, "(-1)"},
|
||||
{true, true, "-(1)"},
|
||||
{true, true, "(+1)"},
|
||||
{true, true, "((+1))"},
|
||||
{true, true, "+(1)"},
|
||||
{true, true, "(~1)"},
|
||||
{true, true, "~(1)"},
|
||||
{true, true, "(!1)"},
|
||||
{true, true, "!(1)"},
|
||||
{true, true, "(1+1)"},
|
||||
{true, true, "(1-1)"},
|
||||
{true, true, "(1*1)"},
|
||||
{true, true, "(1/1)"},
|
||||
{true, true, "(1%2)"},
|
||||
{true, true, "(1<<1)"},
|
||||
{true, true, "(1>>1)"},
|
||||
{true, true, "(1<=>1)"},
|
||||
{true, true, "(1<1)"},
|
||||
{true, true, "(1>1)"},
|
||||
{true, true, "(1<=1)"},
|
||||
{true, true, "(1>=1)"},
|
||||
{true, true, "(1==1)"},
|
||||
{true, true, "(1!=1)"},
|
||||
{true, true, "(1&1)"},
|
||||
{true, true, "(1^1)"},
|
||||
{true, true, "(1|1)"},
|
||||
{true, true, "(1&&1)"},
|
||||
{true, true, "(1||1)"},
|
||||
{true, true, "(1?1:1)"},
|
||||
|
||||
// Accept more complicated "chained" expressions.
|
||||
{true, "1+1+1"},
|
||||
{true, "1+1+1+1"},
|
||||
{true, "1+1+1+1+1"},
|
||||
{true, "1*1*1"},
|
||||
{true, "1*1*1*1"},
|
||||
{true, "1*1*1*1*1"},
|
||||
{true, "1<<1<<1"},
|
||||
{true, "4U>>1>>1"},
|
||||
{true, "1<1<1"},
|
||||
{true, "1>1>1"},
|
||||
{true, "1<=1<=1"},
|
||||
{true, "1>=1>=1"},
|
||||
{true, "1==1==1"},
|
||||
{true, "1!=1!=1"},
|
||||
{true, "1&1&1"},
|
||||
{true, "1^1^1"},
|
||||
{true, "1|1|1"},
|
||||
{true, "1&&1&&1"},
|
||||
{true, "1||1||1"},
|
||||
{true, "1,1,1"},
|
||||
{true, true, "1+1+1"},
|
||||
{true, true, "1+1+1+1"},
|
||||
{true, true, "1+1+1+1+1"},
|
||||
{true, true, "1*1*1"},
|
||||
{true, true, "1*1*1*1"},
|
||||
{true, true, "1*1*1*1*1"},
|
||||
{true, true, "1<<1<<1"},
|
||||
{true, true, "4U>>1>>1"},
|
||||
{true, true, "1<1<1"},
|
||||
{true, true, "1>1>1"},
|
||||
{true, true, "1<=1<=1"},
|
||||
{true, true, "1>=1>=1"},
|
||||
{true, true, "1==1==1"},
|
||||
{true, true, "1!=1!=1"},
|
||||
{true, true, "1&1&1"},
|
||||
{true, true, "1^1^1"},
|
||||
{true, true, "1|1|1"},
|
||||
{true, true, "1&&1&&1"},
|
||||
{true, true, "1||1||1"},
|
||||
{true, true, "(1,1,1)"},
|
||||
|
||||
// Optionally reject comma operator
|
||||
{false, false, "1,1"}
|
||||
};
|
||||
|
||||
TEST_P(MatcherTest, MatchResult) {
|
||||
EXPECT_TRUE(matchText(GetParam().Text) == GetParam().Matched);
|
||||
const MatchParam &Param = GetParam();
|
||||
|
||||
EXPECT_TRUE(matchText(Param.Text, Param.AllowComma) == Param.Matched);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(TokenExpressionParserTests, MatcherTest,
|
||||
::testing::ValuesIn(Params));
|
||||
INSTANTIATE_TEST_SUITE_P(IntegralLiteralExpressionMatcherTests, MatcherTest,
|
||||
::testing::ValuesIn(MatchParams));
|
||||
|
||||
static const SizeParam SizeParams[] = {
|
||||
{modernize::LiteralSize::Int, "1"},
|
||||
{modernize::LiteralSize::UnsignedInt, "1U"},
|
||||
{modernize::LiteralSize::Long, "1L"},
|
||||
{modernize::LiteralSize::UnsignedLong, "1UL"},
|
||||
{modernize::LiteralSize::UnsignedLong, "1LU"},
|
||||
{modernize::LiteralSize::LongLong, "1LL"},
|
||||
{modernize::LiteralSize::UnsignedLongLong, "1ULL"},
|
||||
{modernize::LiteralSize::UnsignedLongLong, "1LLU"}};
|
||||
|
||||
TEST_P(SizeTest, TokenSize) {
|
||||
EXPECT_EQ(sizeText(GetParam().Text), GetParam().Size);
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(IntegralLiteralExpressionMatcherTests, SizeTest,
|
||||
::testing::ValuesIn(SizeParams));
|
||||
|
||||
} // namespace test
|
||||
} // namespace tidy
|
||||
|
|
Loading…
Reference in New Issue