fix #9392 (SymbolDatabase: Weird default constructor outside class) (#2243)

This commit is contained in:
IOBYTE 2019-10-06 01:21:12 -04:00 committed by Daniel Marjamäki
parent 7294145797
commit 8f46bb3ef6
3 changed files with 29 additions and 2 deletions

View File

@ -615,6 +615,12 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
}
// function prototype?
else if (declEnd && declEnd->str() == ";") {
if (tok->previous() && tok->previous()->str() == "::" &&
Token::Match(declEnd->previous(), "default|delete")) {
addClassFunction(&scope, &tok, argStart);
continue;
}
bool newFunc = true; // Is this function already in the database?
for (std::multimap<std::string, const Function *>::const_iterator i = scope->functionMap.find(tok->str()); i != scope->functionMap.end() && i->first == tok->str(); ++i) {
if (Function::argsMatch(scope, i->second->argDef, argStart, emptyString, 0)) {
@ -2378,8 +2384,17 @@ void SymbolDatabase::addClassFunction(Scope **scope, const Token **tok, const To
func->hasBody(true);
} else if (func->type != Function::eDestructor && !destructor) {
// normal function?
if ((*tok)->next()->link()) {
const bool hasConstKeyword = (*tok)->next()->link()->next()->str() == "const";
const Token *closeParen = (*tok)->next()->link();
if (closeParen) {
if (Token::Match(closeParen, ") = default|delete ;")) {
if (closeParen->strAt(2) == "default")
func->isDefault(true);
else
func->isDelete(true);
return;
}
const bool hasConstKeyword = closeParen->next()->str() == "const";
if ((func->isConst() == hasConstKeyword) &&
(func->hasLvalRefQualifier() == lval) &&
(func->hasRvalRefQualifier() == rval)) {

View File

@ -662,6 +662,9 @@ private:
};
class CPPCHECKLIB Function {
// only symbol database can change this
friend class SymbolDatabase;
/** @brief flags mask used to access specific bit. */
enum {
fHasBody = (1 << 0), ///< @brief has implementation

View File

@ -299,6 +299,7 @@ private:
TEST_CASE(symboldatabase76); // #9056
TEST_CASE(symboldatabase77); // #8663
TEST_CASE(symboldatabase78); // #9147
TEST_CASE(symboldatabase79); // #9392
TEST_CASE(createSymbolDatabaseFindAllScopes1);
@ -4246,6 +4247,14 @@ private:
ASSERT_EQUALS("", errout.str());
}
void symboldatabase79() { // #9392
GET_SYMBOL_DB("class C { C(); };\n"
"C::C() = default;");
ASSERT(db->scopeList.size() == 2);
ASSERT(db->scopeList.back().functionList.size() == 1);
ASSERT(db->scopeList.back().functionList.front().isDefault() == true);
}
void createSymbolDatabaseFindAllScopes1() {
GET_SYMBOL_DB("void f() { union {int x; char *p;} a={0}; }");
ASSERT(db->scopeList.size() == 3);