Fixed #4386 (False positive: ctor not detected)
This commit is contained in:
parent
b99d3f0767
commit
63b585424d
|
@ -54,7 +54,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
// find all scopes
|
// find all scopes
|
||||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||||
// Locate next class
|
// Locate next class
|
||||||
if (Token::Match(tok, "class|struct|union|namespace ::| %var% {|:|::")) {
|
if (Token::Match(tok, "class|struct|union|namespace ::| %var% {|:|::") &&
|
||||||
|
tok->strAt(-1) != "friend") {
|
||||||
const Token *tok2 = tok->tokAt(2);
|
const Token *tok2 = tok->tokAt(2);
|
||||||
|
|
||||||
if (tok->strAt(1) == "::")
|
if (tok->strAt(1) == "::")
|
||||||
|
@ -429,10 +430,25 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
}
|
}
|
||||||
|
|
||||||
// friend class declaration?
|
// friend class declaration?
|
||||||
else if (Token::Match(tok, "friend class| %any% ;")) {
|
else if (Token::Match(tok, "friend class| ::| %any% ;|::")) {
|
||||||
Scope::FriendInfo friendInfo;
|
Scope::FriendInfo friendInfo;
|
||||||
|
|
||||||
friendInfo.name = tok->strAt(1) == "class" ? tok->strAt(2) : tok->strAt(1);
|
// save the name start
|
||||||
|
friendInfo.nameStart = tok->strAt(1) == "class" ? tok->tokAt(2) : tok->tokAt(1);
|
||||||
|
friendInfo.nameEnd = friendInfo.nameStart;
|
||||||
|
|
||||||
|
// skip leading "::"
|
||||||
|
if (friendInfo.nameEnd->str() == "::")
|
||||||
|
friendInfo.nameEnd = friendInfo.nameEnd->next();
|
||||||
|
|
||||||
|
// skip qualification "name ::"
|
||||||
|
while (friendInfo.nameEnd && friendInfo.nameEnd->strAt(1) == "::")
|
||||||
|
friendInfo.nameEnd = friendInfo.nameEnd->tokAt(2);
|
||||||
|
|
||||||
|
// save the name
|
||||||
|
if (friendInfo.nameEnd)
|
||||||
|
friendInfo.name = friendInfo.nameEnd->str();
|
||||||
|
|
||||||
// fill this in after parsing is complete
|
// fill this in after parsing is complete
|
||||||
friendInfo.scope = 0;
|
friendInfo.scope = 0;
|
||||||
|
|
||||||
|
@ -641,7 +657,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
for (std::list<Scope::FriendInfo>::iterator i = it->friendList.begin(); i != it->friendList.end(); ++i) {
|
for (std::list<Scope::FriendInfo>::iterator i = it->friendList.begin(); i != it->friendList.end(); ++i) {
|
||||||
for (std::list<Scope>::iterator j = scopeList.begin(); j != scopeList.end(); ++j) {
|
for (std::list<Scope>::iterator j = scopeList.begin(); j != scopeList.end(); ++j) {
|
||||||
// check scope for match
|
// check scope for match
|
||||||
scope = const_cast<Scope*>(j->findQualifiedScope(i->name));
|
scope = findScope(i->nameStart, it->nestedIn);
|
||||||
|
|
||||||
// found match?
|
// found match?
|
||||||
if (scope && scope->isClassOrStruct()) {
|
if (scope && scope->isClassOrStruct()) {
|
||||||
|
@ -1574,6 +1590,24 @@ void SymbolDatabase::printOut(const char *title) const
|
||||||
|
|
||||||
std::cout << " )" << std::endl;
|
std::cout << " )" << std::endl;
|
||||||
|
|
||||||
|
std::cout << " friendList[" << scope->friendList.size() << "] = (";
|
||||||
|
|
||||||
|
std::list<Scope::FriendInfo>::const_iterator fii;
|
||||||
|
|
||||||
|
count = scope->friendList.size();
|
||||||
|
for (fii = scope->friendList.begin(); fii != scope->friendList.end(); ++fii) {
|
||||||
|
if (fii->scope)
|
||||||
|
std::cout << fii->scope->type;
|
||||||
|
else
|
||||||
|
std::cout << " Unknown";
|
||||||
|
|
||||||
|
std::cout << " " << fii->name;
|
||||||
|
if (count-- > 1)
|
||||||
|
std::cout << ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << " )" << std::endl;
|
||||||
|
|
||||||
std::cout << " nestedIn: " << scope->nestedIn;
|
std::cout << " nestedIn: " << scope->nestedIn;
|
||||||
if (scope->nestedIn) {
|
if (scope->nestedIn) {
|
||||||
std::cout << " " << scope->nestedIn->type << " "
|
std::cout << " " << scope->nestedIn->type << " "
|
||||||
|
|
|
@ -445,6 +445,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FriendInfo {
|
struct FriendInfo {
|
||||||
|
const Token *nameStart;
|
||||||
|
const Token *nameEnd;
|
||||||
std::string name;
|
std::string name;
|
||||||
Scope *scope;
|
Scope *scope;
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,6 +50,7 @@ private:
|
||||||
TEST_CASE(noConstructor3);
|
TEST_CASE(noConstructor3);
|
||||||
TEST_CASE(noConstructor4);
|
TEST_CASE(noConstructor4);
|
||||||
TEST_CASE(noConstructor5);
|
TEST_CASE(noConstructor5);
|
||||||
|
TEST_CASE(noConstructor6); // ticket #4386
|
||||||
|
|
||||||
TEST_CASE(operatorEq1);
|
TEST_CASE(operatorEq1);
|
||||||
TEST_CASE(operatorEq2);
|
TEST_CASE(operatorEq2);
|
||||||
|
@ -1881,6 +1882,20 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void noConstructor6() {
|
||||||
|
// ticket #4386
|
||||||
|
checkNoConstructor("class Ccpucycles {\n"
|
||||||
|
" friend class foo::bar;\n"
|
||||||
|
" Ccpucycles() :\n"
|
||||||
|
" m_v(0), m_b(true)\n"
|
||||||
|
" {}\n"
|
||||||
|
"private:\n"
|
||||||
|
" cpucyclesT m_v;\n"
|
||||||
|
" bool m_b;\n"
|
||||||
|
"};\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void checkNoMemset(const char code[]) {
|
void checkNoMemset(const char code[]) {
|
||||||
// Clear the error log
|
// Clear the error log
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
Loading…
Reference in New Issue