Skip to content

Commit c02acea

Browse files
IOBYTEdanmar
authored andcommitted
Fixed danmar#6614 (false positive: (style) The class 'A' does not have a constructor.)
1 parent 77e22da commit c02acea

File tree

2 files changed

+56
-32
lines changed

2 files changed

+56
-32
lines changed

lib/symboldatabase.cpp

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,44 +1303,47 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
13031303
tok1 = tok1->tokAt(-1);
13041304
}
13051305

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-
}
1306+
// done if constructor or destructor
1307+
if (!Token::Match(tok1, "{|}|;|public:|protected:|private:") && tok1) {
1308+
// skip over pointers and references
1309+
while (Token::Match(tok1, "[*&]"))
1310+
tok1 = tok1->tokAt(-1);
13171311

1318-
// function can't have number or variable as return type
1319-
if (tok1 && (tok1->isNumber() || tok1->varId()))
1320-
return false;
1312+
// skip over template
1313+
if (tok1 && tok1->str() == ">") {
1314+
if (tok1->link())
1315+
tok1 = tok1->link()->previous();
1316+
else
1317+
return false;
1318+
}
13211319

1322-
// skip over return type
1323-
if (Token::Match(tok1, "%name%")) {
1324-
if (tok1->str() == "return")
1320+
// function can't have number or variable as return type
1321+
if (tok1 && (tok1->isNumber() || tok1->varId()))
13251322
return false;
1326-
tok1 = tok1->previous();
1327-
}
13281323

1329-
// skip over qualification
1330-
while (Token::simpleMatch(tok1, "::")) {
1331-
if (Token::Match(tok1->tokAt(-1), "%name%"))
1332-
tok1 = tok1->tokAt(-2);
1333-
else
1334-
tok1 = tok1->tokAt(-1);
1335-
}
1324+
// skip over return type
1325+
if (Token::Match(tok1, "%name%")) {
1326+
if (tok1->str() == "return")
1327+
return false;
1328+
tok1 = tok1->previous();
1329+
}
13361330

1337-
// skip over modifiers and other stuff
1338-
while (Token::Match(tok1, "const|static|extern|template|virtual|struct|class"))
1339-
tok1 = tok1->previous();
1331+
// skip over qualification
1332+
while (Token::simpleMatch(tok1, "::")) {
1333+
if (Token::Match(tok1->tokAt(-1), "%name%"))
1334+
tok1 = tok1->tokAt(-2);
1335+
else
1336+
tok1 = tok1->tokAt(-1);
1337+
}
13401338

1341-
// should be at a sequence point if this is a function
1342-
if (!Token::Match(tok1, ">|{|}|;|public:|protected:|private:") && tok1)
1343-
return false;
1339+
// skip over modifiers and other stuff
1340+
while (Token::Match(tok1, "const|static|extern|template|virtual|struct|class"))
1341+
tok1 = tok1->previous();
1342+
1343+
// should be at a sequence point if this is a function
1344+
if (!Token::Match(tok1, ">|{|}|;|public:|protected:|private:") && tok1)
1345+
return false;
1346+
}
13441347

13451348
const Token* tok2 = tok->next()->link()->next();
13461349
if (tok2 &&

test/testconstructors.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class TestConstructors : public TestFixture {
7373
TEST_CASE(noConstructor7); // ticket #4391
7474
TEST_CASE(noConstructor8); // ticket #4404
7575
TEST_CASE(noConstructor9); // ticket #4419
76+
TEST_CASE(noConstructor10); // ticket #6614
7677

7778
TEST_CASE(forwardDeclaration); // ticket #4290/#3190
7879

@@ -509,6 +510,26 @@ class TestConstructors : public TestFixture {
509510
ASSERT_EQUALS("", errout.str());
510511
}
511512

513+
void noConstructor10() {
514+
// ticket #6614
515+
check("class A : public wxDialog\n"
516+
"{\n"
517+
"private:\n"
518+
" DECLARE_EVENT_TABLE()\n"
519+
"public:\n"
520+
" A(wxWindow *parent,\n"
521+
" wxWindowID id = 1,\n"
522+
" const wxString &title = wxT(""),\n"
523+
" const wxPoint& pos = wxDefaultPosition,\n"
524+
" const wxSize& size = wxDefaultSize,\n"
525+
" long style = wxDIALOG_NO_PARENT | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX);\n"
526+
" virtual ~A();\n"
527+
"private:\n"
528+
" wxTimer *WxTimer1;\n"
529+
"};\n");
530+
ASSERT_EQUALS("", errout.str());
531+
}
532+
512533
// ticket #4290 "False Positive: style (noConstructor): The class 'foo' does not have a constructor."
513534
// ticket #3190 "SymbolDatabase: Parse of sub class constructor fails"
514535
void forwardDeclaration() {

0 commit comments

Comments
 (0)