Skip to content

Commit 1845378

Browse files
IOBYTEdanmar
authored andcommitted
Don't remove the volatile keyword so we can properly overload functions. (cppcheck-opensource#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.
1 parent 5452c4d commit 1845378

8 files changed

Lines changed: 66 additions & 35 deletions

lib/checkother.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,11 @@ void CheckOther::warningOldStylePointerCast()
278278
tok = scope->bodyStart;
279279
for (; tok && tok != scope->bodyEnd; tok = tok->next()) {
280280
// Old style pointer casting..
281-
if (!Token::Match(tok, "( const| %type% * const| ) (| %name%|%num%|%bool%|%char%|%str%"))
281+
if (!Token::Match(tok, "( const|volatile| const|volatile| %type% * const| ) (| %name%|%num%|%bool%|%char%|%str%"))
282282
continue;
283283

284284
// skip first "const" in "const Type* const"
285-
if (tok->strAt(1) == "const")
285+
while (Token::Match(tok->next(), "const|volatile"))
286286
tok = tok->next();
287287
const Token* typeTok = tok->next();
288288
// skip second "const" in "const Type* const"
@@ -326,7 +326,7 @@ void CheckOther::invalidPointerCast()
326326
const Token* toTok = nullptr;
327327
const Token* fromTok = nullptr;
328328
// Find cast
329-
if (Token::Match(tok, "( const| %type% %type%| const| * )")) {
329+
if (Token::Match(tok, "( const|volatile| const|volatile| %type% %type%| const| * )")) {
330330
toTok = tok;
331331
fromTok = tok->astOperand1();
332332
} else if (Token::simpleMatch(tok, "reinterpret_cast <") && tok->linkAt(1)) {

lib/symboldatabase.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,8 +1406,8 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
14061406
tok1 = tok1->link()->tokAt(-2);
14071407
}
14081408

1409-
// skip over const, noexcept, throw and override specifiers
1410-
while (Token::Match(tok2, "const|noexcept|throw|override|final")) {
1409+
// skip over const, noexcept, throw, override, final and volatile specifiers
1410+
while (Token::Match(tok2, "const|noexcept|throw|override|final|volatile")) {
14111411
tok2 = tok2->next();
14121412
if (tok2 && tok2->str() == "(")
14131413
tok2 = tok2->link()->next();
@@ -1646,9 +1646,9 @@ void Variable::evaluate(const Library* lib)
16461646
tok = tok->next();
16471647
}
16481648

1649-
while (Token::Match(_start, "static|const %any%"))
1649+
while (Token::Match(_start, "static|const|volatile %any%"))
16501650
_start = _start->next();
1651-
while (_end && _end->previous() && _end->str() == "const")
1651+
while (_end && _end->previous() && Token::Match(_end, "const|volatile"))
16521652
_end = _end->previous();
16531653

16541654
if (_start) {
@@ -1793,6 +1793,8 @@ Function::Function(const Tokenizer *_tokenizer, const Token *tok, const Scope *s
17931793
setFlag(fHasOverrideSpecifier, true);
17941794
else if (tok->str() == "final")
17951795
setFlag(fHasFinalSpecifier, true);
1796+
else if (tok->str() == "volatile")
1797+
isVolatile(true);
17961798
else if (tok->str() == "noexcept") {
17971799
isNoExcept(!Token::simpleMatch(tok->next(), "( false )"));
17981800
if (tok->next()->str() == "(")
@@ -2703,6 +2705,7 @@ void SymbolDatabase::printOut(const char *title) const
27032705
std::cout << " hasLvalRefQual: " << func->hasLvalRefQualifier() << std::endl;
27042706
std::cout << " hasRvalRefQual: " << func->hasRvalRefQualifier() << std::endl;
27052707
std::cout << " isVariadic: " << func->isVariadic() << std::endl;
2708+
std::cout << " isVolatile: " << func->isVolatile() << std::endl;
27062709
std::cout << " attributes:";
27072710
if (func->isAttributeConst())
27082711
std::cout << " const ";
@@ -3057,7 +3060,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
30573060

30583061
const Token *typeTok = startTok;
30593062
// skip over stuff to get to type
3060-
while (Token::Match(typeTok, "const|enum|struct|::"))
3063+
while (Token::Match(typeTok, "const|volatile|enum|struct|::"))
30613064
typeTok = typeTok->next();
30623065
if (Token::Match(typeTok, ",|)")) { // #8333
30633066
symbolDatabase->_tokenizer->syntaxError(typeTok);
@@ -3069,7 +3072,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
30693072

30703073
// check for argument with no name or missing varid
30713074
if (!endTok) {
3072-
if (tok->previous()->isName() && tok->strAt(-1) != "const") {
3075+
if (tok->previous()->isName() && !Token::Match(tok->tokAt(-1), "const|volatile")) {
30733076
if (tok->previous() != typeTok) {
30743077
nameTok = tok->previous();
30753078
endTok = nameTok->previous();
@@ -3100,7 +3103,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
31003103
}
31013104

31023105
// skip over stuff before type
3103-
while (Token::Match(startTok, "enum|struct|const"))
3106+
while (Token::Match(startTok, "enum|struct|const|volatile"))
31043107
startTok = startTok->next();
31053108

31063109
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
34343437
return next;
34353438
}
34363439

3437-
// skip const|static|mutable|extern
3438-
while (Token::Match(tok, "const|static|mutable|extern")) {
3440+
// skip const|volatile|static|mutable|extern
3441+
while (Token::Match(tok, "const|volatile|static|mutable|extern")) {
34393442
tok = tok->next();
34403443
}
34413444

lib/symboldatabase.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,8 @@ class CPPCHECKLIB Function {
672672
fIsOperator = (1 << 16), ///< @brief is operator
673673
fHasLvalRefQual = (1 << 17), ///< @brief has & lvalue ref-qualifier
674674
fHasRvalRefQual = (1 << 18), ///< @brief has && rvalue ref-qualifier
675-
fIsVariadic = (1 << 19) ///< @brief is variadic
675+
fIsVariadic = (1 << 19), ///< @brief is variadic
676+
fIsVolatile = (1 << 20) ///< @brief is volatile
676677
};
677678

678679
/**
@@ -808,6 +809,9 @@ class CPPCHECKLIB Function {
808809
bool isVariadic() const {
809810
return getFlag(fIsVariadic);
810811
}
812+
bool isVolatile() const {
813+
return getFlag(fIsVolatile);
814+
}
811815

812816
void hasBody(bool state) {
813817
setFlag(fHasBody, state);
@@ -893,6 +897,9 @@ class CPPCHECKLIB Function {
893897
void isVariadic(bool state) {
894898
setFlag(fIsVariadic, state);
895899
}
900+
void isVolatile(bool state) {
901+
setFlag(fIsVolatile, state);
902+
}
896903
};
897904

898905
class CPPCHECKLIB Scope {

lib/tokenize.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3635,7 +3635,7 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
36353635
if (_settings->terminated())
36363636
return false;
36373637

3638-
// Remove "volatile", "inline", "register", and "restrict"
3638+
// Remove "inline", "register", and "restrict"
36393639
simplifyKeyword();
36403640

36413641
// simplify simple calculations inside <..>
@@ -4169,7 +4169,7 @@ void Tokenizer::removeMacrosInGlobalScope()
41694169
if (tok->str() == "(") {
41704170
tok = tok->link();
41714171
if (Token::Match(tok, ") %type% {") &&
4172-
!Token::Match(tok->next(), "const|namespace|class|struct|union|noexcept|override|final"))
4172+
!Token::Match(tok->next(), "const|namespace|class|struct|union|noexcept|override|final|volatile"))
41734173
tok->deleteNext();
41744174
}
41754175

@@ -5521,10 +5521,10 @@ void Tokenizer::simplifyFunctionPointers()
55215521
Token *endTok = tok->link()->next()->link();
55225522
if (Token::simpleMatch(endTok, ") throw ("))
55235523
endTok = endTok->linkAt(2);
5524-
if (!Token::Match(endTok, ") const| ;|,|)|=|[|{"))
5524+
if (!Token::Match(endTok, ") const|volatile| const|volatile| ;|,|)|=|[|{"))
55255525
continue;
55265526

5527-
if (endTok->strAt(1) == "const")
5527+
while (Token::Match(endTok->next(), "const|volatile"))
55285528
endTok->deleteNext();
55295529

55305530
// ok simplify this function pointer to an ordinary pointer
@@ -8960,16 +8960,15 @@ void Tokenizer::simplifyCPPAttribute()
89608960
}
89618961

89628962
static const std::set<std::string> keywords = {
8963-
"volatile"
8964-
, "inline"
8963+
"inline"
89658964
, "_inline"
89668965
, "__inline"
89678966
, "__forceinline"
89688967
, "register"
89698968
, "__restrict"
89708969
, "__restrict__"
89718970
};
8972-
// Remove "volatile", "inline", "register", "restrict", "override", "final", "static" and "constexpr"
8971+
// Remove "inline", "register", "restrict", "override", "final", "static" and "constexpr"
89738972
// "restrict" keyword
89748973
// - New to 1999 ANSI/ISO C standard
89758974
// - Not in C++ standard yet

test/testpostfixoperator.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,7 @@ class TestPostfixOperator : public TestFixture {
238238
" std::cout << k << std::endl;\n"
239239
" return 0;\n"
240240
"}");
241-
TODO_ASSERT_EQUALS("",
242-
"[test.cpp:6]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str());
241+
ASSERT_EQUALS("[test.cpp:6]: (performance) Prefer prefix ++/-- operators for non-primitive types.\n", errout.str());
243242
}
244243

245244
void testiterator() {

test/testsimplifytypedef.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,7 +1187,7 @@ class TestSimplifyTypedef : public TestFixture {
11871187
void simplifyTypedef39() {
11881188
const char code[] = "typedef int A;\n"
11891189
"template <const A, volatile A> struct S{};";
1190-
const char expected[] = "template < const int , int > struct S { } ;";
1190+
const char expected[] = "template < const int , volatile int > struct S { } ;";
11911191
ASSERT_EQUALS(expected, tok(code, false));
11921192
ASSERT_EQUALS("", errout.str());
11931193
}
@@ -1478,7 +1478,7 @@ class TestSimplifyTypedef : public TestFixture {
14781478
"_Iterator v3;";
14791479

14801480
// The expected result..
1481-
const char expected[] = "long * const v1 ; "
1481+
const char expected[] = "volatile long * const v1 ; "
14821482
"void * const v2 [ 2 ] ; "
14831483
"int * const * v3 ;";
14841484
ASSERT_EQUALS(expected, tok(code));
@@ -2931,16 +2931,16 @@ class TestSimplifyTypedef : public TestFixture {
29312931
// The expected result..
29322932
const char expected[] = "int * t1 ; " // simplified to regular pointer
29332933
"int * const t2 ; "
2934-
"int * t3 ; " // volatile removed, gets simplified to regular pointer
2935-
"int * const t4 ; " // volatile removed
2934+
"int * volatile t3 ; "
2935+
"int * const volatile t4 ; "
29362936
"int * t5 ; "
29372937
"int * const t6 ; "
2938-
"int * t7 ; " // volatile removed
2939-
"int * const t8 ; " // volatile removed
2938+
"int * volatile t7 ; "
2939+
"int * const volatile t8 ; "
29402940
"int ( :: C :: * t9 ) ( float ) ; "
29412941
"int ( :: C :: * const t10 ) ( float ) ; "
2942-
"int ( :: C :: * t11 ) ( float ) ; " // volatile removed
2943-
"int ( :: C :: * const t12 ) ( float ) ;"; // volatile removed
2942+
"int ( :: C :: * volatile t11 ) ( float ) ; "
2943+
"int ( :: C :: * const volatile t12 ) ( float ) ;";
29442944
ASSERT_EQUALS(expected, tok(code, false));
29452945
ASSERT_EQUALS("", errout.str());
29462946
}
@@ -3005,8 +3005,8 @@ class TestSimplifyTypedef : public TestFixture {
30053005
// The expected result..
30063006
const char expected[] = ":: C ( :: C :: * f1 ) ( ) ; "
30073007
":: C ( :: C :: * f2 ) ( ) const ; "
3008-
":: C ( :: C :: * f3 ) ( ) ; "
3009-
":: C ( :: C :: * f4 ) ( ) const ;";
3008+
":: C ( :: C :: * f3 ) ( ) volatile ; "
3009+
":: C ( :: C :: * f4 ) ( ) const volatile ;";
30103010
ASSERT_EQUALS(expected, tok(code));
30113011
ASSERT_EQUALS("", errout.str());
30123012
}
@@ -3043,8 +3043,8 @@ class TestSimplifyTypedef : public TestFixture {
30433043
// The expected result..
30443044
const char expected[] = ":: B :: C ( :: B :: C :: * f1 ) ( ) ; "
30453045
":: B :: C ( :: B :: C :: * f2 ) ( ) const ; "
3046-
":: B :: C ( :: B :: C :: * f3 ) ( ) ; "
3047-
":: B :: C ( :: B :: C :: * f4 ) ( ) const ;";
3046+
":: B :: C ( :: B :: C :: * f3 ) ( ) volatile ; "
3047+
":: B :: C ( :: B :: C :: * f4 ) ( ) const volatile ;";
30483048
ASSERT_EQUALS(expected, tok(code));
30493049
ASSERT_EQUALS("", errout.str());
30503050
}

test/testsymboldatabase.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ class TestSymbolDatabase: public TestFixture {
286286
TEST_CASE(symboldatabase66); // #8540
287287
TEST_CASE(symboldatabase67); // #8538
288288
TEST_CASE(symboldatabase68); // #8560
289+
TEST_CASE(symboldatabase69);
289290

290291
TEST_CASE(enum1);
291292
TEST_CASE(enum2);
@@ -3864,6 +3865,28 @@ class TestSymbolDatabase: public TestFixture {
38643865
ASSERT(f && f->function() && f->function()->isNoExcept());
38653866
}
38663867

3868+
void symboldatabase69() {
3869+
GET_SYMBOL_DB("struct Fred {\n"
3870+
" int x, y;\n"
3871+
" void foo() volatile { }\n"
3872+
" void foo() const { }\n"
3873+
" void foo() { }\n"
3874+
"};");
3875+
const Token *f = db ? Token::findsimplematch(tokenizer.tokens(), "foo ( ) volatile {") : nullptr;
3876+
ASSERT(f != nullptr);
3877+
ASSERT(f && f->function() && f->function()->token->linenr() == 3);
3878+
ASSERT(f && f->function() && f->function()->isVolatile());
3879+
f = db ? Token::findsimplematch(tokenizer.tokens(), "foo ( ) const {") : nullptr;
3880+
ASSERT(f != nullptr);
3881+
ASSERT(f && f->function() && f->function()->token->linenr() == 4);
3882+
ASSERT(f && f->function() && f->function()->isConst());
3883+
f = db ? Token::findsimplematch(tokenizer.tokens(), "foo ( ) {") : nullptr;
3884+
ASSERT(f != nullptr);
3885+
ASSERT(f && f->function() && f->function()->token->linenr() == 5);
3886+
ASSERT(f && f->function() && !f->function()->isVolatile());
3887+
ASSERT(f && f->function() && !f->function()->isConst());
3888+
}
3889+
38673890
void enum1() {
38683891
GET_SYMBOL_DB("enum BOOL { FALSE, TRUE }; enum BOOL b;");
38693892

test/testtokenize.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4033,7 +4033,7 @@ class TestTokenizer : public TestFixture {
40334033

40344034
const std::string actual(tokenizeAndStringify(code));
40354035

4036-
ASSERT_EQUALS("int a ; a = 0 ;\nint b ; b = 0 ;\nint c ; c = 0 ;", actual);
4036+
ASSERT_EQUALS("volatile int a ; a = 0 ;\nvolatile int b ; b = 0 ;\nvolatile int c ; c = 0 ;", actual);
40374037
}
40384038

40394039

0 commit comments

Comments
 (0)