Skip to content

Commit 130ffc5

Browse files
IOBYTEdanmar
authored andcommitted
Fixed cppcheck-opensource#6538 (Symboldatabase: improve isFunction)
1 parent b9cc5b5 commit 130ffc5

6 files changed

Lines changed: 91 additions & 7 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,57 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
12881288
(tok->previous()->isName() || tok->strAt(-1) == ">" || tok->strAt(-1) == "&" || tok->strAt(-1) == "*" || // Either a return type in front of tok
12891289
tok->strAt(-1) == "::" || tok->strAt(-1) == "~" || // or a scope qualifier in front of tok
12901290
outerScope->isClassOrStruct())) { // or a ctor/dtor
1291+
1292+
const Token* tok1 = tok->previous();
1293+
1294+
// skip over destructor "~"
1295+
if (tok1->str() == "~")
1296+
tok1 = tok1->previous();
1297+
1298+
// skip over qualification
1299+
while (Token::simpleMatch(tok1, "::")) {
1300+
if (Token::Match(tok1->tokAt(-1), "%name%"))
1301+
tok1 = tok1->tokAt(-2);
1302+
else
1303+
tok1 = tok1->tokAt(-1);
1304+
}
1305+
1306+
// skip over pointers and references
1307+
while (Token::Match(tok1, "[*&]"))
1308+
tok1 = tok1->tokAt(-1);
1309+
1310+
// skip over template
1311+
if (tok1 && tok1->str() == ">") {
1312+
if (tok1->link())
1313+
tok1 = tok1->link()->previous();
1314+
else
1315+
return false;
1316+
}
1317+
1318+
// function can't have number or variable as return type
1319+
if (tok1 && (tok1->isNumber() || tok1->varId()))
1320+
return false;
1321+
1322+
// skip over return type
1323+
if (Token::Match(tok1, "%name%"))
1324+
tok1 = tok1->previous();
1325+
1326+
// skip over qualification
1327+
while (Token::simpleMatch(tok1, "::")) {
1328+
if (Token::Match(tok1->tokAt(-1), "%name%"))
1329+
tok1 = tok1->tokAt(-2);
1330+
else
1331+
tok1 = tok1->tokAt(-1);
1332+
}
1333+
1334+
// skip over modifiers and other stuff
1335+
while (Token::Match(tok1, "const|static|extern|template|virtual|struct|class"))
1336+
tok1 = tok1->previous();
1337+
1338+
// should be at a sequence point if this is a function
1339+
if (!Token::Match(tok1, ">|{|}|;|public:|protected:|private:") && tok1)
1340+
return false;
1341+
12911342
const Token* tok2 = tok->next()->link()->next();
12921343
if (tok2 &&
12931344
(Token::Match(tok2, "const| ;|{|=") ||

test/testautovariables.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class TestAutoVariables : public TestFixture {
8080
TEST_CASE(testautovar12); // ticket #5024 - crash
8181
TEST_CASE(testautovar13); // ticket #5537 - crash
8282
TEST_CASE(testautovar14); // ticket #4776 - assignment of function parameter, goto
83+
TEST_CASE(testautovar15); // ticket #6538
8384
TEST_CASE(testautovar_array1);
8485
TEST_CASE(testautovar_array2);
8586
TEST_CASE(testautovar_return1);
@@ -390,6 +391,19 @@ class TestAutoVariables : public TestFixture {
390391
ASSERT_EQUALS("", errout.str());
391392
}
392393

394+
void testautovar15() { // Ticket #6538
395+
check("static const float4 darkOutline(0.05f, 0.05f, 0.05f, 0.95f);\n"
396+
"static const float darkLuminosity = 0.05 +\n"
397+
" 0.0722f * math::powf(darkOutline[2], 2.2);\n"
398+
"const float4* ChooseOutlineColor(const float4& textColor) {\n"
399+
" const float lumdiff = something;\n"
400+
" if (lumdiff > 5.0f)\n"
401+
" return &darkOutline;\n"
402+
" return 0;\n"
403+
"}", false, false);
404+
ASSERT_EQUALS("", errout.str());
405+
}
406+
393407
void testautovar_array1() {
394408
check("void func1(int* arr[2])\n"
395409
"{\n"

test/testgarbage.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -420,11 +420,11 @@ class TestGarbage : public TestFixture {
420420

421421
ASSERT_THROW(checkCode("class Foo {}; class Bar : public Foo"), InternalError);
422422

423-
ASSERT_THROW(checkCode("YY_DECL { switch (yy_act) {\n"
424-
" case 65: YY_BREAK\n"
425-
" case YY_STATE_EOF(block):\n"
426-
" yyterminate(); \n"
427-
"} }"), InternalError); // #5663
423+
checkCode("YY_DECL { switch (yy_act) {\n"
424+
" case 65: YY_BREAK\n"
425+
" case YY_STATE_EOF(block):\n"
426+
" yyterminate(); \n"
427+
"} }"); // #5663
428428
}
429429

430430
void garbageAST() {

test/testother.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3020,7 +3020,7 @@ class TestOther : public TestFixture {
30203020
ASSERT_EQUALS("[test.cpp:4]: (style) Consecutive return, break, continue, goto or throw statements are unnecessary.\n", errout.str());
30213021

30223022
// #5707
3023-
check("extern int i,j\n"
3023+
check("extern int i,j;\n"
30243024
"int foo() {\n"
30253025
" switch(i) {\n"
30263026
" default: j=1; break;\n"

test/testsymboldatabase.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ class TestSymbolDatabase: public TestFixture {
228228
TEST_CASE(symboldatabase48); // #6417
229229
TEST_CASE(symboldatabase49); // #6424
230230
TEST_CASE(symboldatabase50); // #6432
231+
TEST_CASE(symboldatabase51); // #6538
231232

232233
TEST_CASE(isImplicitlyVirtual);
233234

@@ -2128,6 +2129,24 @@ class TestSymbolDatabase: public TestFixture {
21282129
ASSERT_EQUALS(true, db && f && f->function() && f->function()->isConstructor());
21292130
}
21302131

2132+
void symboldatabase51() { // #6538
2133+
GET_SYMBOL_DB("static const float f1 = 2 * foo1(a, b);\n"
2134+
"static const float f2 = 2 * ::foo2(a, b);\n"
2135+
"static const float f3 = 2 * std::foo3(a, b);\n"
2136+
"static const float f4 = c * foo4(a, b);\n"
2137+
"static const int i1 = 2 & foo5(a, b);\n"
2138+
"static const bool b1 = 2 > foo6(a, b);\n");
2139+
ASSERT(db != nullptr);
2140+
if (db) {
2141+
ASSERT(findFunctionByName("foo1", &db->scopeList.front()) == nullptr);
2142+
ASSERT(findFunctionByName("foo2", &db->scopeList.front()) == nullptr);
2143+
ASSERT(findFunctionByName("foo3", &db->scopeList.front()) == nullptr);
2144+
ASSERT(findFunctionByName("foo4", &db->scopeList.front()) == nullptr);
2145+
ASSERT(findFunctionByName("foo5", &db->scopeList.front()) == nullptr);
2146+
ASSERT(findFunctionByName("foo6", &db->scopeList.front()) == nullptr);
2147+
}
2148+
}
2149+
21312150
void isImplicitlyVirtual() {
21322151
{
21332152
GET_SYMBOL_DB("class Base {\n"

test/testunusedprivfunc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ class TestUnusedPrivateFunction : public TestFixture {
418418
"class A\n"
419419
"{\n"
420420
"public:\n"
421-
" A()\n"
421+
" A();\n"
422422
" void a();\n"
423423
"private:\n"
424424
" void b();\n"

0 commit comments

Comments
 (0)