Remove constexpr -> const simplification (#3346)
This commit is contained in:
parent
561e9174fa
commit
00eb71fd49
|
@ -1410,11 +1410,11 @@ bool isConstFunctionCall(const Token* ftok, const Library& library)
|
|||
if (const Function* f = ftok->function()) {
|
||||
if (f->isAttributePure() || f->isAttributeConst())
|
||||
return true;
|
||||
if (Function::returnsVoid(f))
|
||||
return false;
|
||||
// Any modified arguments
|
||||
if (functionModifiesArguments(f))
|
||||
return false;
|
||||
if (Function::returnsVoid(f))
|
||||
return false;
|
||||
// Member function call
|
||||
if (Token::simpleMatch(ftok->previous(), ".")) {
|
||||
if (f->isConst())
|
||||
|
@ -1437,8 +1437,7 @@ bool isConstFunctionCall(const Token* ftok, const Library& library)
|
|||
}
|
||||
return false;
|
||||
} else if (f->argumentList.empty()) {
|
||||
// TODO: Check for constexpr
|
||||
return false;
|
||||
return f->isConstexpr();
|
||||
}
|
||||
} else if (const Library::Function* f = library.getFunction(ftok)) {
|
||||
if (f->ispure)
|
||||
|
|
|
@ -1985,7 +1985,10 @@ void Variable::evaluate(const Settings* settings)
|
|||
setFlag(fIsMutable, true);
|
||||
else if (tok->str() == "const")
|
||||
setFlag(fIsConst, true);
|
||||
else if (tok->str() == "*") {
|
||||
else if (tok->str() == "constexpr") {
|
||||
setFlag(fIsConst, true);
|
||||
setFlag(fIsStatic, true);
|
||||
} else if (tok->str() == "*") {
|
||||
setFlag(fIsPointer, !isArray() || Token::Match(tok->previous(), "( * %name% )"));
|
||||
setFlag(fIsConst, false); // Points to const, isn't necessarily const itself
|
||||
} else if (tok->str() == "&") {
|
||||
|
@ -2007,7 +2010,7 @@ void Variable::evaluate(const Settings* settings)
|
|||
tok = tok->next();
|
||||
}
|
||||
|
||||
while (Token::Match(mTypeStartToken, "static|const|volatile %any%"))
|
||||
while (Token::Match(mTypeStartToken, "static|const|constexpr|volatile %any%"))
|
||||
mTypeStartToken = mTypeStartToken->next();
|
||||
while (mTypeEndToken && mTypeEndToken->previous() && Token::Match(mTypeEndToken, "const|volatile"))
|
||||
mTypeEndToken = mTypeEndToken->previous();
|
||||
|
@ -2300,6 +2303,11 @@ const Token *Function::setFlags(const Token *tok1, const Scope *scope)
|
|||
isFriend(true);
|
||||
}
|
||||
|
||||
// constexpr function
|
||||
else if (tok1->str() == "constexpr") {
|
||||
isConstexpr(true);
|
||||
}
|
||||
|
||||
// Function template
|
||||
else if (tok1->link() && tok1->str() == ">" && Token::simpleMatch(tok1->link()->previous(), "template <")) {
|
||||
templateDef = tok1->link()->previous();
|
||||
|
@ -4309,7 +4317,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess, con
|
|||
}
|
||||
|
||||
// skip const|volatile|static|mutable|extern
|
||||
while (tok->isKeyword() && Token::Match(tok, "const|volatile|static|mutable|extern")) {
|
||||
while (tok->isKeyword() && Token::Match(tok, "const|constexpr|volatile|static|mutable|extern")) {
|
||||
tok = tok->next();
|
||||
}
|
||||
|
||||
|
@ -6126,7 +6134,7 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype, V
|
|||
type->type() && type->type()->isTypeAlias() && type->type()->typeStart &&
|
||||
type->type()->typeStart->str() != type->str() && type->type()->typeStart != previousType)
|
||||
parsedecl(type->type()->typeStart, valuetype, defaultSignedness, settings);
|
||||
else if (type->str() == "const")
|
||||
else if (Token::Match(type, "const|constexpr"))
|
||||
valuetype->constness |= (1 << (valuetype->pointer - pointer0));
|
||||
else if (settings->clang && type->str().size() > 2 && type->str().find("::") < type->str().find("<")) {
|
||||
TokenList typeTokens(settings);
|
||||
|
|
|
@ -723,6 +723,7 @@ class CPPCHECKLIB Function {
|
|||
fHasTrailingReturnType = (1 << 21), ///< @brief has trailing return type
|
||||
fIsEscapeFunction = (1 << 22), ///< @brief Function throws or exits
|
||||
fIsInlineKeyword = (1 << 23), ///< @brief Function has "inline" keyword
|
||||
fIsConstexpr = (1 << 24), ///< @brief is constexpr
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -889,6 +890,13 @@ public:
|
|||
void isEscapeFunction(bool state) {
|
||||
setFlag(fIsEscapeFunction, state);
|
||||
}
|
||||
|
||||
bool isConstexpr() const {
|
||||
return getFlag(fIsConstexpr);
|
||||
}
|
||||
void isConstexpr(bool state) {
|
||||
setFlag(fIsConstexpr, state);
|
||||
}
|
||||
bool isSafe(const Settings *settings) const;
|
||||
|
||||
const Token *tokenDef; ///< function name token in class definition
|
||||
|
|
|
@ -7259,15 +7259,15 @@ void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, co
|
|||
|
||||
//check if variable is declared 'const' or 'static' or both
|
||||
while (tok2) {
|
||||
if (!Token::Match(tok2, "const|static") && Token::Match(tok2, "%type% const|static")) {
|
||||
if (!Token::Match(tok2, "const|static|constexpr") && Token::Match(tok2, "%type% const|static")) {
|
||||
tok2 = tok2->next();
|
||||
++typelen;
|
||||
}
|
||||
|
||||
if (tok2->str() == "const")
|
||||
if (Token::Match(tok2, "const|constexpr"))
|
||||
isconst = true;
|
||||
|
||||
else if (tok2->str() == "static")
|
||||
else if (Token::Match(tok2, "static|constexpr"))
|
||||
isstatic = true;
|
||||
|
||||
else if (Token::Match(tok2, "%type% :: %type%")) {
|
||||
|
@ -11202,11 +11202,6 @@ void Tokenizer::simplifyKeyword()
|
|||
}
|
||||
|
||||
else if (cpp11) {
|
||||
if (tok->str() == "constexpr") {
|
||||
tok->originalName(tok->str());
|
||||
tok->str("const");
|
||||
}
|
||||
|
||||
// final:
|
||||
// 1) struct name final { }; <- struct is final
|
||||
if (Token::Match(tok->previous(), "struct|class|union %type% final [:{]")) {
|
||||
|
|
|
@ -123,6 +123,7 @@ void TokenList::determineCppC()
|
|||
//mKeywords.insert("bool"); // type
|
||||
mKeywords.insert("catch");
|
||||
mKeywords.insert("class");
|
||||
mKeywords.insert("constexpr");
|
||||
mKeywords.insert("const_cast");
|
||||
mKeywords.insert("decltype");
|
||||
mKeywords.insert("delete");
|
||||
|
@ -666,7 +667,7 @@ static bool iscpp11init_impl(const Token * const tok)
|
|||
endtok = nameToken->linkAt(1);
|
||||
else
|
||||
return false;
|
||||
if (Token::Match(nameToken, "else|try|do|const|override|volatile|&|&&"))
|
||||
if (Token::Match(nameToken, "else|try|do|const|constexpr|override|volatile|&|&&"))
|
||||
return false;
|
||||
if (Token::simpleMatch(nameToken->previous(), "namespace"))
|
||||
return false;
|
||||
|
@ -956,7 +957,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
|
|||
if (Token::simpleMatch(squareBracket->link(), "] (")) {
|
||||
Token* const roundBracket = squareBracket->link()->next();
|
||||
Token* curlyBracket = roundBracket->link()->next();
|
||||
while (Token::Match(curlyBracket, "mutable|const"))
|
||||
while (Token::Match(curlyBracket, "mutable|const|constexpr"))
|
||||
curlyBracket = curlyBracket->next();
|
||||
if (Token::simpleMatch(curlyBracket, "noexcept ("))
|
||||
curlyBracket = curlyBracket->linkAt(1)->next();
|
||||
|
|
|
@ -2178,9 +2178,8 @@ struct ValueFlowAnalyzer : Analyzer {
|
|||
|
||||
// bailout: global non-const variables
|
||||
if (isGlobal() && Token::Match(tok, "%name% (") && !Token::simpleMatch(tok->linkAt(1), ") {")) {
|
||||
// TODO: Check for constexpr functions
|
||||
if (tok->function()) {
|
||||
if (!isConstFunctionCall(tok, getSettings()->library))
|
||||
if (!tok->function()->isConstexpr() && !isConstFunctionCall(tok, getSettings()->library))
|
||||
return Action::Invalid;
|
||||
} else if (getSettings()->library.getFunction(tok)) {
|
||||
// Assume library function doesn't modify user-global variables
|
||||
|
|
|
@ -2296,10 +2296,10 @@ private:
|
|||
"long f1 = fib<1>;\n"
|
||||
"long f2 = fib<2>;\n"
|
||||
"long f3 = fib<3>;";
|
||||
const char exp[] = "const long fib<2> = fib<1> + fib<0> ; "
|
||||
"const long fib<3> = fib<2> + fib<1> ; "
|
||||
"const long fib<0> = 0 ; "
|
||||
"const long fib<1> = 1 ; "
|
||||
const char exp[] = "constexpr long fib<2> = fib<1> + fib<0> ; "
|
||||
"constexpr long fib<3> = fib<2> + fib<1> ; "
|
||||
"constexpr long fib<0> = 0 ; "
|
||||
"constexpr long fib<1> = 1 ; "
|
||||
"long f0 ; f0 = fib<0> ; "
|
||||
"long f1 ; f1 = fib<1> ; "
|
||||
"long f2 ; f2 = fib<2> ; "
|
||||
|
@ -2314,12 +2314,12 @@ private:
|
|||
"template<>\n"
|
||||
" constexpr long fib<1> = 1;\n"
|
||||
"long f5 = fib<5>;\n";
|
||||
const char exp[] = "const long fib<5> = fib<4> + fib<3> ; "
|
||||
"const long fib<4> = fib<3> + fib<2> ; "
|
||||
"const long fib<3> = fib<2> + fib<1> ; "
|
||||
"const long fib<2> = fib<1> + fib<0> ; "
|
||||
"const long fib<0> = 0 ; "
|
||||
"const long fib<1> = 1 ; "
|
||||
const char exp[] = "constexpr long fib<5> = fib<4> + fib<3> ; "
|
||||
"constexpr long fib<4> = fib<3> + fib<2> ; "
|
||||
"constexpr long fib<3> = fib<2> + fib<1> ; "
|
||||
"constexpr long fib<2> = fib<1> + fib<0> ; "
|
||||
"constexpr long fib<0> = 0 ; "
|
||||
"constexpr long fib<1> = 1 ; "
|
||||
"long f5 ; f5 = fib<5> ;";
|
||||
ASSERT_EQUALS(exp, tok(code));
|
||||
}
|
||||
|
@ -2933,8 +2933,8 @@ private:
|
|||
"constexpr auto funcBraced = [](auto x){ return T{x};};\n"
|
||||
"double f(int x) { return func<double>(x); }\n"
|
||||
"double fBraced(int x) { return funcBraced<int>(x); }";
|
||||
const char exp[] = "const auto func<double> = [ ] ( auto x ) { return double ( x ) ; } ; "
|
||||
"const auto funcBraced<int> = [ ] ( auto x ) { return int { x } ; } ; "
|
||||
const char exp[] = "constexpr auto func<double> = [ ] ( auto x ) { return double ( x ) ; } ; "
|
||||
"constexpr auto funcBraced<int> = [ ] ( auto x ) { return int { x } ; } ; "
|
||||
"double f ( int x ) { return func<double> ( x ) ; } "
|
||||
"double fBraced ( int x ) { return funcBraced<int> ( x ) ; }";
|
||||
ASSERT_EQUALS(exp, tok(code));
|
||||
|
@ -2946,8 +2946,8 @@ private:
|
|||
" func<int>(x);\n"
|
||||
" func<double>(x);\n"
|
||||
"}";
|
||||
const char exp[] = "const auto func<int> = [ ] ( auto x ) { return int ( x ) ; } ; "
|
||||
"const auto func<double> = [ ] ( auto x ) { return double ( x ) ; } ; "
|
||||
const char exp[] = "constexpr auto func<int> = [ ] ( auto x ) { return int ( x ) ; } ; "
|
||||
"constexpr auto func<double> = [ ] ( auto x ) { return double ( x ) ; } ; "
|
||||
"void foo ( ) { "
|
||||
"func<int> ( x ) ; "
|
||||
"func<double> ( x ) ; "
|
||||
|
@ -3084,19 +3084,19 @@ private:
|
|||
"a<int> c ; "
|
||||
"template < typename d > "
|
||||
"template < typename b > "
|
||||
"const decltype ( auto ) a < d > :: operator() ( b && ) const { } "
|
||||
"constexpr decltype ( auto ) a < d > :: operator() ( b && ) const { } "
|
||||
"struct a<int> { "
|
||||
"template < typename b > const decltype ( auto ) operator() ( b && ) const ; "
|
||||
"template < typename b > constexpr decltype ( auto ) operator() ( b && ) const ; "
|
||||
"} ;";
|
||||
const char act[] = "struct a<int> ; "
|
||||
"a<int> c ; "
|
||||
"template < typename d > "
|
||||
"template < typename b > "
|
||||
"const decltype ( auto ) a < d > :: operator() ( b && ) const { } "
|
||||
"constexpr decltype ( auto ) a < d > :: operator() ( b && ) const { } "
|
||||
"struct a<int> { "
|
||||
"template < typename b > const decltype ( auto ) operator() ( b && ) const ; "
|
||||
"template < typename b > constexpr decltype ( auto ) operator() ( b && ) const ; "
|
||||
"} ; "
|
||||
"const decltype ( auto ) a<int> :: operator() ( b && ) const { }";
|
||||
"constexpr decltype ( auto ) a<int> :: operator() ( b && ) const { }";
|
||||
TODO_ASSERT_EQUALS(exp, act, tok(code));
|
||||
}
|
||||
{
|
||||
|
@ -3270,7 +3270,7 @@ private:
|
|||
" return foo<TrueFalse>();\n"
|
||||
"}";
|
||||
const char exp[] = "struct TrueFalse { "
|
||||
"static const bool v ( ) { return true ; } "
|
||||
"static constexpr bool v ( ) { return true ; } "
|
||||
"} ; "
|
||||
"int global ; "
|
||||
"int foo<TrueFalse> ( ) ; "
|
||||
|
@ -3538,11 +3538,11 @@ private:
|
|||
"static_assert(!e<f<char>>());\n"
|
||||
"}";
|
||||
const char exp[] = "namespace a { "
|
||||
"const bool e<f<char>> ( ) ; "
|
||||
"constexpr bool e<f<char>> ( ) ; "
|
||||
"class f<char> ; "
|
||||
"static_assert ( ! e<f<char>> ( ) ) ; } "
|
||||
"class a :: f<char> { f<char> ( a :: f < b :: d > ) ; } ; "
|
||||
"const bool a :: e<f<char>> ( ) { return false ; }";
|
||||
"constexpr bool a :: e<f<char>> ( ) { return false ; }";
|
||||
ASSERT_EQUALS(exp, tok(code));
|
||||
}
|
||||
}
|
||||
|
@ -3584,7 +3584,7 @@ private:
|
|||
"using A3 = enum B3 {b = 0;};\n"
|
||||
"A3<int> a3;";
|
||||
const char exp[] = "template < int N > "
|
||||
"using A1 = struct B1 { static const auto value = N ; } ; "
|
||||
"using A1 = struct B1 { static auto constexpr value = N ; } ; "
|
||||
"A1 < 0 > a1 ; "
|
||||
"template < class T > "
|
||||
"using A2 = struct B2 { void f ( T ) { } } ; "
|
||||
|
@ -4807,7 +4807,7 @@ private:
|
|||
|
||||
//both of these should work but in cppcheck 2.1 only the first option will work (ticket #9843)
|
||||
{
|
||||
const std::string expected = "template < long Num > const bool foo < bar < Num > > = true ;";
|
||||
const std::string expected = "template < long Num > constexpr bool foo < bar < Num > > = true ;";
|
||||
ASSERT_EQUALS(expected,
|
||||
tok("template <long Num>\n"
|
||||
"constexpr bool foo<bar<Num> > = true;\n"));
|
||||
|
@ -5974,28 +5974,28 @@ private:
|
|||
{
|
||||
const char code[] = "template<class T> constexpr T pi = T(3.1415926535897932385L);\n"
|
||||
"float x = pi<float>;";
|
||||
const char expected[] = "const float pi<float> = float ( 3.1415926535897932385L ) ; "
|
||||
const char expected[] = "constexpr float pi<float> = float ( 3.1415926535897932385L ) ; "
|
||||
"float x ; x = pi<float> ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
{
|
||||
const char code[] = "template<class> constexpr float pi = float(3.1415926535897932385L);\n"
|
||||
"float x = pi<float>;";
|
||||
const char expected[] = "const float pi<float> = float ( 3.1415926535897932385L ) ; "
|
||||
const char expected[] = "constexpr float pi<float> = float ( 3.1415926535897932385L ) ; "
|
||||
"float x ; x = pi<float> ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
{
|
||||
const char code[] = "template<class T = float> constexpr T pi = T(3.1415926535897932385L);\n"
|
||||
"float x = pi<float>;";
|
||||
const char expected[] = "const float pi<float> = float ( 3.1415926535897932385L ) ; "
|
||||
const char expected[] = "constexpr float pi<float> = float ( 3.1415926535897932385L ) ; "
|
||||
"float x ; x = pi<float> ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
{
|
||||
const char code[] = "template<class T = float> constexpr T pi = T(3.1415926535897932385L);\n"
|
||||
"float x = pi<>;";
|
||||
const char expected[] = "const float pi<float> = float ( 3.1415926535897932385L ) ; "
|
||||
const char expected[] = "constexpr float pi<float> = float ( 3.1415926535897932385L ) ; "
|
||||
"float x ; x = pi<float> ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
|
@ -6005,35 +6005,35 @@ private:
|
|||
{
|
||||
const char code[] = "template<class T, int N> constexpr T foo = T(N*N);\n"
|
||||
"float x = foo<float,7>;";
|
||||
const char expected[] = "const float foo<float,7> = float ( 49 ) ; "
|
||||
const char expected[] = "constexpr float foo<float,7> = float ( 49 ) ; "
|
||||
"float x ; x = foo<float,7> ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
{
|
||||
const char code[] = "template<class,int> constexpr float foo = float(7);\n"
|
||||
"float x = foo<float,7>;";
|
||||
const char expected[] = "const float foo<float,7> = float ( 7 ) ; "
|
||||
const char expected[] = "constexpr float foo<float,7> = float ( 7 ) ; "
|
||||
"float x ; x = foo<float,7> ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
{
|
||||
const char code[] = "template<class T = float, int N = 7> constexpr T foo = T(7);\n"
|
||||
"double x = foo<double, 14>;";
|
||||
const char expected[] = "const double foo<double,14> = double ( 7 ) ; "
|
||||
const char expected[] = "constexpr double foo<double,14> = double ( 7 ) ; "
|
||||
"double x ; x = foo<double,14> ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
{
|
||||
const char code[] = "template<class T = float, int N = 7> constexpr T foo = T(7);\n"
|
||||
"float x = foo<>;";
|
||||
const char expected[] = "const float foo<float,7> = float ( 7 ) ; "
|
||||
const char expected[] = "constexpr float foo<float,7> = float ( 7 ) ; "
|
||||
"float x ; x = foo<float,7> ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
{
|
||||
const char code[] = "template<class T = float, int N = 7> constexpr T foo = T(7);\n"
|
||||
"double x = foo<double>;";
|
||||
const char expected[] = "const double foo<double,7> = double ( 7 ) ; "
|
||||
const char expected[] = "constexpr double foo<double,7> = double ( 7 ) ; "
|
||||
"double x ; x = foo<double,7> ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
}
|
||||
|
|
|
@ -4894,7 +4894,7 @@ private:
|
|||
ASSERT_EQUALS("int foo ( ) { }", tok("inline int foo ( ) { }", true));
|
||||
ASSERT_EQUALS("int foo ( ) { }", tok("__inline int foo ( ) { }", true));
|
||||
ASSERT_EQUALS("int foo ( ) { }", tok("__forceinline int foo ( ) { }", true));
|
||||
ASSERT_EQUALS("const int foo ( ) { }", tok("constexpr int foo() { }", true));
|
||||
ASSERT_EQUALS("constexpr int foo ( ) { }", tok("constexpr int foo() { }", true));
|
||||
ASSERT_EQUALS("void f ( ) { int final [ 10 ] ; }", tok("void f() { int final[10]; }", true));
|
||||
ASSERT_EQUALS("int * p ;", tok("int * __restrict p;", "test.c"));
|
||||
ASSERT_EQUALS("int * * p ;", tok("int * __restrict__ * p;", "test.c"));
|
||||
|
|
|
@ -2584,7 +2584,7 @@ private:
|
|||
" constexpr const foo &c_str() const noexcept { return _a; }\n"
|
||||
"};";
|
||||
|
||||
const char exp [] = "class c { char _a [ 4 ] ; const const char ( & c_str ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
|
||||
const char exp [] = "class c { char _a [ 4 ] ; const constexpr char ( & c_str ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
|
||||
ASSERT_EQUALS(exp, tok(code, false));
|
||||
}
|
||||
|
||||
|
@ -2595,7 +2595,7 @@ private:
|
|||
" constexpr operator foo &() const noexcept { return _a; }\n"
|
||||
"};";
|
||||
|
||||
const char actual [] = "class c { char _a [ 4 ] ; const operatorchar ( & ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
|
||||
const char actual [] = "class c { char _a [ 4 ] ; constexpr operatorchar ( & ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
|
||||
const char exp [] = "class c { char _a [ 4 ] ; const operator char ( & ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
|
||||
TODO_ASSERT_EQUALS(exp, actual, tok(code, false));
|
||||
}
|
||||
|
@ -2607,7 +2607,7 @@ private:
|
|||
" constexpr operator const foo &() const noexcept { return _a; }\n"
|
||||
"};";
|
||||
|
||||
const char actual [] = "class c { char _a [ 4 ] ; const operatorconstchar ( & ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
|
||||
const char actual [] = "class c { char _a [ 4 ] ; constexpr operatorconstchar ( & ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
|
||||
const char exp [] = "class c { char _a [ 4 ] ; const operator const char ( & ( ) const noexcept ) [ 4 ] { return _a ; } } ;";
|
||||
TODO_ASSERT_EQUALS(exp, actual, tok(code, false));
|
||||
}
|
||||
|
|
|
@ -165,6 +165,7 @@ private:
|
|||
TEST_CASE(isVariablePointerToConstVolatilePointer);
|
||||
TEST_CASE(isVariableMultiplePointersAndQualifiers);
|
||||
TEST_CASE(variableVolatile);
|
||||
TEST_CASE(variableConstexpr);
|
||||
TEST_CASE(isVariableDecltype);
|
||||
|
||||
TEST_CASE(VariableValueType1);
|
||||
|
@ -208,6 +209,7 @@ private:
|
|||
TEST_CASE(functionDeclarationTemplate);
|
||||
TEST_CASE(functionDeclarations);
|
||||
TEST_CASE(functionDeclarations2);
|
||||
TEST_CASE(constexprFunction);
|
||||
TEST_CASE(constructorInitialization);
|
||||
TEST_CASE(memberFunctionOfUnknownClassMacro1);
|
||||
TEST_CASE(memberFunctionOfUnknownClassMacro2);
|
||||
|
@ -1317,6 +1319,20 @@ private:
|
|||
ASSERT(y->variable()->isVolatile());
|
||||
}
|
||||
|
||||
void variableConstexpr() {
|
||||
GET_SYMBOL_DB("constexpr int x = 16;");
|
||||
|
||||
const Token *x = Token::findsimplematch(tokenizer.tokens(), "x");
|
||||
ASSERT(x);
|
||||
ASSERT(x->variable());
|
||||
ASSERT(x->variable()->isConst());
|
||||
ASSERT(x->variable()->isStatic());
|
||||
ASSERT(x->valueType());
|
||||
ASSERT(x->valueType()->pointer == 0);
|
||||
ASSERT(x->valueType()->constness == 1);
|
||||
ASSERT(x->valueType()->reference == Reference::None);
|
||||
}
|
||||
|
||||
void isVariableDecltype() {
|
||||
GET_SYMBOL_DB("int x;\n"
|
||||
"decltype(x) a;\n"
|
||||
|
@ -1877,6 +1893,24 @@ private:
|
|||
ASSERT(parenthesis->valueType()->type == ValueType::Type::CONTAINER);
|
||||
}
|
||||
|
||||
void constexprFunction() {
|
||||
GET_SYMBOL_DB_STD("constexpr int foo();");
|
||||
|
||||
// 1 scopes: Global
|
||||
ASSERT(db && db->scopeList.size() == 1);
|
||||
|
||||
const Scope *scope = &db->scopeList.front();
|
||||
|
||||
ASSERT(scope && scope->functionList.size() == 1);
|
||||
|
||||
const Function *foo = &scope->functionList.front();
|
||||
|
||||
ASSERT(foo);
|
||||
ASSERT(foo->tokenDef->str() == "foo");
|
||||
ASSERT(!foo->hasBody());
|
||||
ASSERT(foo->isConstexpr());
|
||||
}
|
||||
|
||||
void constructorInitialization() {
|
||||
GET_SYMBOL_DB("std::string logfile;\n"
|
||||
"std::ofstream log(logfile.c_str(), std::ios::out);");
|
||||
|
|
|
@ -4852,12 +4852,12 @@ private:
|
|||
void simplifyOperatorName14() { // std::complex operator "" if
|
||||
{
|
||||
const char code[] = "constexpr std::complex<float> operator\"\"if(long double __num);";
|
||||
ASSERT_EQUALS("const std :: complex < float > operator\"\"if ( long double __num ) ;",
|
||||
ASSERT_EQUALS("constexpr std :: complex < float > operator\"\"if ( long double __num ) ;",
|
||||
tokenizeAndStringify(code));
|
||||
}
|
||||
{
|
||||
const char code[] = "constexpr std::complex<float> operator\"\"if(long double __num) { }";
|
||||
ASSERT_EQUALS("const std :: complex < float > operator\"\"if ( long double __num ) { }",
|
||||
ASSERT_EQUALS("constexpr std :: complex < float > operator\"\"if ( long double __num ) { }",
|
||||
tokenizeAndStringify(code));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2803,6 +2803,16 @@ private:
|
|||
" x->c();\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 8U, 0));
|
||||
|
||||
code = "constexpr int f();\n"
|
||||
"int g() {\n"
|
||||
" if (f() == 1) {\n"
|
||||
" int x = f();\n"
|
||||
" return x;\n"
|
||||
" }\n"
|
||||
" return 0;\n"
|
||||
"}\n";
|
||||
ASSERT_EQUALS(true, testValueOfXKnown(code, 5U, 1));
|
||||
}
|
||||
|
||||
void valueFlowAfterConditionExpr() {
|
||||
|
|
Loading…
Reference in New Issue