Don't remove the volatile keyword so we can properly overload functions. (#1218)
* Don't remove the volatile keyword so we can properly overload functions. I fixed all the checks that had tests that use volatile. There will probably be more changes needed due to lack of test coverage for volatile in some checks. * Fix unused private function warning.
This commit is contained in:
parent
5452c4dc4a
commit
184537884f
|
@ -278,11 +278,11 @@ void CheckOther::warningOldStylePointerCast()
|
|||
tok = scope->bodyStart;
|
||||
for (; tok && tok != scope->bodyEnd; tok = tok->next()) {
|
||||
// Old style pointer casting..
|
||||
if (!Token::Match(tok, "( const| %type% * const| ) (| %name%|%num%|%bool%|%char%|%str%"))
|
||||
if (!Token::Match(tok, "( const|volatile| const|volatile| %type% * const| ) (| %name%|%num%|%bool%|%char%|%str%"))
|
||||
continue;
|
||||
|
||||
// skip first "const" in "const Type* const"
|
||||
if (tok->strAt(1) == "const")
|
||||
while (Token::Match(tok->next(), "const|volatile"))
|
||||
tok = tok->next();
|
||||
const Token* typeTok = tok->next();
|
||||
// skip second "const" in "const Type* const"
|
||||
|
@ -326,7 +326,7 @@ void CheckOther::invalidPointerCast()
|
|||
const Token* toTok = nullptr;
|
||||
const Token* fromTok = nullptr;
|
||||
// Find cast
|
||||
if (Token::Match(tok, "( const| %type% %type%| const| * )")) {
|
||||
if (Token::Match(tok, "( const|volatile| const|volatile| %type% %type%| const| * )")) {
|
||||
toTok = tok;
|
||||
fromTok = tok->astOperand1();
|
||||
} else if (Token::simpleMatch(tok, "reinterpret_cast <") && tok->linkAt(1)) {
|
||||
|
|
|
@ -1406,8 +1406,8 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
|||
tok1 = tok1->link()->tokAt(-2);
|
||||
}
|
||||
|
||||
// skip over const, noexcept, throw and override specifiers
|
||||
while (Token::Match(tok2, "const|noexcept|throw|override|final")) {
|
||||
// skip over const, noexcept, throw, override, final and volatile specifiers
|
||||
while (Token::Match(tok2, "const|noexcept|throw|override|final|volatile")) {
|
||||
tok2 = tok2->next();
|
||||
if (tok2 && tok2->str() == "(")
|
||||
tok2 = tok2->link()->next();
|
||||
|
@ -1646,9 +1646,9 @@ void Variable::evaluate(const Library* lib)
|
|||
tok = tok->next();
|
||||
}
|
||||
|
||||
while (Token::Match(_start, "static|const %any%"))
|
||||
while (Token::Match(_start, "static|const|volatile %any%"))
|
||||
_start = _start->next();
|
||||
while (_end && _end->previous() && _end->str() == "const")
|
||||
while (_end && _end->previous() && Token::Match(_end, "const|volatile"))
|
||||
_end = _end->previous();
|
||||
|
||||
if (_start) {
|
||||
|
@ -1793,6 +1793,8 @@ Function::Function(const Tokenizer *_tokenizer, const Token *tok, const Scope *s
|
|||
setFlag(fHasOverrideSpecifier, true);
|
||||
else if (tok->str() == "final")
|
||||
setFlag(fHasFinalSpecifier, true);
|
||||
else if (tok->str() == "volatile")
|
||||
isVolatile(true);
|
||||
else if (tok->str() == "noexcept") {
|
||||
isNoExcept(!Token::simpleMatch(tok->next(), "( false )"));
|
||||
if (tok->next()->str() == "(")
|
||||
|
@ -2703,6 +2705,7 @@ void SymbolDatabase::printOut(const char *title) const
|
|||
std::cout << " hasLvalRefQual: " << func->hasLvalRefQualifier() << std::endl;
|
||||
std::cout << " hasRvalRefQual: " << func->hasRvalRefQualifier() << std::endl;
|
||||
std::cout << " isVariadic: " << func->isVariadic() << std::endl;
|
||||
std::cout << " isVolatile: " << func->isVolatile() << std::endl;
|
||||
std::cout << " attributes:";
|
||||
if (func->isAttributeConst())
|
||||
std::cout << " const ";
|
||||
|
@ -3057,7 +3060,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
|||
|
||||
const Token *typeTok = startTok;
|
||||
// skip over stuff to get to type
|
||||
while (Token::Match(typeTok, "const|enum|struct|::"))
|
||||
while (Token::Match(typeTok, "const|volatile|enum|struct|::"))
|
||||
typeTok = typeTok->next();
|
||||
if (Token::Match(typeTok, ",|)")) { // #8333
|
||||
symbolDatabase->_tokenizer->syntaxError(typeTok);
|
||||
|
@ -3069,7 +3072,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
|||
|
||||
// check for argument with no name or missing varid
|
||||
if (!endTok) {
|
||||
if (tok->previous()->isName() && tok->strAt(-1) != "const") {
|
||||
if (tok->previous()->isName() && !Token::Match(tok->tokAt(-1), "const|volatile")) {
|
||||
if (tok->previous() != typeTok) {
|
||||
nameTok = tok->previous();
|
||||
endTok = nameTok->previous();
|
||||
|
@ -3100,7 +3103,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
|||
}
|
||||
|
||||
// skip over stuff before type
|
||||
while (Token::Match(startTok, "enum|struct|const"))
|
||||
while (Token::Match(startTok, "enum|struct|const|volatile"))
|
||||
startTok = startTok->next();
|
||||
|
||||
argumentList.emplace_back(nameTok, startTok, endTok, count++, Argument, argType, functionScope, &symbolDatabase->_settings->library);
|
||||
|
@ -3434,8 +3437,8 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess, con
|
|||
return next;
|
||||
}
|
||||
|
||||
// skip const|static|mutable|extern
|
||||
while (Token::Match(tok, "const|static|mutable|extern")) {
|
||||
// skip const|volatile|static|mutable|extern
|
||||
while (Token::Match(tok, "const|volatile|static|mutable|extern")) {
|
||||
tok = tok->next();
|
||||
}
|
||||
|
||||
|
|
|
@ -672,7 +672,8 @@ class CPPCHECKLIB Function {
|
|||
fIsOperator = (1 << 16), ///< @brief is operator
|
||||
fHasLvalRefQual = (1 << 17), ///< @brief has & lvalue ref-qualifier
|
||||
fHasRvalRefQual = (1 << 18), ///< @brief has && rvalue ref-qualifier
|
||||
fIsVariadic = (1 << 19) ///< @brief is variadic
|
||||
fIsVariadic = (1 << 19), ///< @brief is variadic
|
||||
fIsVolatile = (1 << 20) ///< @brief is volatile
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -808,6 +809,9 @@ public:
|
|||
bool isVariadic() const {
|
||||
return getFlag(fIsVariadic);
|
||||
}
|
||||
bool isVolatile() const {
|
||||
return getFlag(fIsVolatile);
|
||||
}
|
||||
|
||||
void hasBody(bool state) {
|
||||
setFlag(fHasBody, state);
|
||||
|
@ -893,6 +897,9 @@ private:
|
|||
void isVariadic(bool state) {
|
||||
setFlag(fIsVariadic, state);
|
||||
}
|
||||
void isVolatile(bool state) {
|
||||
setFlag(fIsVolatile, state);
|
||||
}
|
||||
};
|
||||
|
||||
class CPPCHECKLIB Scope {
|
||||
|
|
|
@ -3635,7 +3635,7 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
|
|||
if (_settings->terminated())
|
||||
return false;
|
||||
|
||||
// Remove "volatile", "inline", "register", and "restrict"
|
||||
// Remove "inline", "register", and "restrict"
|
||||
simplifyKeyword();
|
||||
|
||||
// simplify simple calculations inside <..>
|
||||
|
@ -4169,7 +4169,7 @@ void Tokenizer::removeMacrosInGlobalScope()
|
|||
if (tok->str() == "(") {
|
||||
tok = tok->link();
|
||||
if (Token::Match(tok, ") %type% {") &&
|
||||
!Token::Match(tok->next(), "const|namespace|class|struct|union|noexcept|override|final"))
|
||||
!Token::Match(tok->next(), "const|namespace|class|struct|union|noexcept|override|final|volatile"))
|
||||
tok->deleteNext();
|
||||
}
|
||||
|
||||
|
@ -5521,10 +5521,10 @@ void Tokenizer::simplifyFunctionPointers()
|
|||
Token *endTok = tok->link()->next()->link();
|
||||
if (Token::simpleMatch(endTok, ") throw ("))
|
||||
endTok = endTok->linkAt(2);
|
||||
if (!Token::Match(endTok, ") const| ;|,|)|=|[|{"))
|
||||
if (!Token::Match(endTok, ") const|volatile| const|volatile| ;|,|)|=|[|{"))
|
||||
continue;
|
||||
|
||||
if (endTok->strAt(1) == "const")
|
||||
while (Token::Match(endTok->next(), "const|volatile"))
|
||||
endTok->deleteNext();
|
||||
|
||||
// ok simplify this function pointer to an ordinary pointer
|
||||
|
@ -8960,8 +8960,7 @@ void Tokenizer::simplifyCPPAttribute()
|
|||
}
|
||||
|
||||
static const std::set<std::string> keywords = {
|
||||
"volatile"
|
||||
, "inline"
|
||||
"inline"
|
||||
, "_inline"
|
||||
, "__inline"
|
||||
, "__forceinline"
|
||||
|
@ -8969,7 +8968,7 @@ static const std::set<std::string> keywords = {
|
|||
, "__restrict"
|
||||
, "__restrict__"
|
||||
};
|
||||
// Remove "volatile", "inline", "register", "restrict", "override", "final", "static" and "constexpr"
|
||||
// Remove "inline", "register", "restrict", "override", "final", "static" and "constexpr"
|
||||
// "restrict" keyword
|
||||
// - New to 1999 ANSI/ISO C standard
|
||||
// - Not in C++ standard yet
|
||||
|
|
|
@ -238,8 +238,7 @@ private:
|
|||
" std::cout << k << std::endl;\n"
|
||||
" return 0;\n"
|
||||
"}");
|
||||
TODO_ASSERT_EQUALS("",
|
||||
"[test.cpp:6]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:6]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str());
|
||||
}
|
||||
|
||||
void testiterator() {
|
||||
|
|
|
@ -1187,7 +1187,7 @@ private:
|
|||
void simplifyTypedef39() {
|
||||
const char code[] = "typedef int A;\n"
|
||||
"template <const A, volatile A> struct S{};";
|
||||
const char expected[] = "template < const int , int > struct S { } ;";
|
||||
const char expected[] = "template < const int , volatile int > struct S { } ;";
|
||||
ASSERT_EQUALS(expected, tok(code, false));
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
@ -1478,7 +1478,7 @@ private:
|
|||
"_Iterator v3;";
|
||||
|
||||
// The expected result..
|
||||
const char expected[] = "long * const v1 ; "
|
||||
const char expected[] = "volatile long * const v1 ; "
|
||||
"void * const v2 [ 2 ] ; "
|
||||
"int * const * v3 ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
|
@ -2931,16 +2931,16 @@ private:
|
|||
// The expected result..
|
||||
const char expected[] = "int * t1 ; " // simplified to regular pointer
|
||||
"int * const t2 ; "
|
||||
"int * t3 ; " // volatile removed, gets simplified to regular pointer
|
||||
"int * const t4 ; " // volatile removed
|
||||
"int * volatile t3 ; "
|
||||
"int * const volatile t4 ; "
|
||||
"int * t5 ; "
|
||||
"int * const t6 ; "
|
||||
"int * t7 ; " // volatile removed
|
||||
"int * const t8 ; " // volatile removed
|
||||
"int * volatile t7 ; "
|
||||
"int * const volatile t8 ; "
|
||||
"int ( :: C :: * t9 ) ( float ) ; "
|
||||
"int ( :: C :: * const t10 ) ( float ) ; "
|
||||
"int ( :: C :: * t11 ) ( float ) ; " // volatile removed
|
||||
"int ( :: C :: * const t12 ) ( float ) ;"; // volatile removed
|
||||
"int ( :: C :: * volatile t11 ) ( float ) ; "
|
||||
"int ( :: C :: * const volatile t12 ) ( float ) ;";
|
||||
ASSERT_EQUALS(expected, tok(code, false));
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
@ -3005,8 +3005,8 @@ private:
|
|||
// The expected result..
|
||||
const char expected[] = ":: C ( :: C :: * f1 ) ( ) ; "
|
||||
":: C ( :: C :: * f2 ) ( ) const ; "
|
||||
":: C ( :: C :: * f3 ) ( ) ; "
|
||||
":: C ( :: C :: * f4 ) ( ) const ;";
|
||||
":: C ( :: C :: * f3 ) ( ) volatile ; "
|
||||
":: C ( :: C :: * f4 ) ( ) const volatile ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
@ -3043,8 +3043,8 @@ private:
|
|||
// The expected result..
|
||||
const char expected[] = ":: B :: C ( :: B :: C :: * f1 ) ( ) ; "
|
||||
":: B :: C ( :: B :: C :: * f2 ) ( ) const ; "
|
||||
":: B :: C ( :: B :: C :: * f3 ) ( ) ; "
|
||||
":: B :: C ( :: B :: C :: * f4 ) ( ) const ;";
|
||||
":: B :: C ( :: B :: C :: * f3 ) ( ) volatile ; "
|
||||
":: B :: C ( :: B :: C :: * f4 ) ( ) const volatile ;";
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
|
|
@ -286,6 +286,7 @@ private:
|
|||
TEST_CASE(symboldatabase66); // #8540
|
||||
TEST_CASE(symboldatabase67); // #8538
|
||||
TEST_CASE(symboldatabase68); // #8560
|
||||
TEST_CASE(symboldatabase69);
|
||||
|
||||
TEST_CASE(enum1);
|
||||
TEST_CASE(enum2);
|
||||
|
@ -3864,6 +3865,28 @@ private:
|
|||
ASSERT(f && f->function() && f->function()->isNoExcept());
|
||||
}
|
||||
|
||||
void symboldatabase69() {
|
||||
GET_SYMBOL_DB("struct Fred {\n"
|
||||
" int x, y;\n"
|
||||
" void foo() volatile { }\n"
|
||||
" void foo() const { }\n"
|
||||
" void foo() { }\n"
|
||||
"};");
|
||||
const Token *f = db ? Token::findsimplematch(tokenizer.tokens(), "foo ( ) volatile {") : nullptr;
|
||||
ASSERT(f != nullptr);
|
||||
ASSERT(f && f->function() && f->function()->token->linenr() == 3);
|
||||
ASSERT(f && f->function() && f->function()->isVolatile());
|
||||
f = db ? Token::findsimplematch(tokenizer.tokens(), "foo ( ) const {") : nullptr;
|
||||
ASSERT(f != nullptr);
|
||||
ASSERT(f && f->function() && f->function()->token->linenr() == 4);
|
||||
ASSERT(f && f->function() && f->function()->isConst());
|
||||
f = db ? Token::findsimplematch(tokenizer.tokens(), "foo ( ) {") : nullptr;
|
||||
ASSERT(f != nullptr);
|
||||
ASSERT(f && f->function() && f->function()->token->linenr() == 5);
|
||||
ASSERT(f && f->function() && !f->function()->isVolatile());
|
||||
ASSERT(f && f->function() && !f->function()->isConst());
|
||||
}
|
||||
|
||||
void enum1() {
|
||||
GET_SYMBOL_DB("enum BOOL { FALSE, TRUE }; enum BOOL b;");
|
||||
|
||||
|
|
|
@ -4033,7 +4033,7 @@ private:
|
|||
|
||||
const std::string actual(tokenizeAndStringify(code));
|
||||
|
||||
ASSERT_EQUALS("int a ; a = 0 ;\nint b ; b = 0 ;\nint c ; c = 0 ;", actual);
|
||||
ASSERT_EQUALS("volatile int a ; a = 0 ;\nvolatile int b ; b = 0 ;\nvolatile int c ; c = 0 ;", actual);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue