Fix valueFlowBailoutIncompleteVar for cast and template args (refs #10045) (#5452)

This commit is contained in:
chrchr-github 2023-09-16 13:03:14 +02:00 committed by GitHub
parent df4457e895
commit 0c51977f86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 14 deletions

View File

@ -1478,6 +1478,14 @@ void SymbolDatabase::createSymbolDatabaseIncompleteVars()
continue;
if (tok->varId() != 0)
continue;
if (tok->isCast() && !isCPPCast(tok) && tok->link() && tok->str() == "(") {
tok = tok->link();
continue;
}
if (Token::Match(tok, "catch|typeid (")) {
tok = tok->linkAt(1);
continue;
}
if (!tok->isNameOnly())
continue;
if (tok->type())
@ -1486,16 +1494,14 @@ void SymbolDatabase::createSymbolDatabaseIncompleteVars()
continue;
if (Token::Match(tok->next(), "&|&&|* )|,|%var%"))
continue;
if (Token::simpleMatch(tok->next(), ")") && Token::simpleMatch(tok->next()->link()->previous(), "catch ("))
continue;
// Very likely a typelist
if (Token::Match(tok->tokAt(-2), "%type% ,") || Token::Match(tok->next(), ", %type%"))
continue;
// Inside template brackets
if (Token::Match(tok->next(), "<|>") && tok->next()->link())
continue;
if (Token::simpleMatch(tok->previous(), "<") && tok->previous()->link())
if (Token::simpleMatch(tok->next(), "<") && tok->linkAt(1)) {
tok = tok->linkAt(1);
continue;
}
// Skip goto labels
if (Token::simpleMatch(tok->previous(), "goto"))
continue;

View File

@ -5432,15 +5432,37 @@ private:
void createSymbolDatabaseIncompleteVars()
{
GET_SYMBOL_DB("void f() {\n"
" auto s1 = std::string{ \"abc\" };\n"
" auto s2 = std::string(\"def\");\n"
"}\n");
ASSERT(db && errout.str().empty());
const Token* s1 = Token::findsimplematch(tokenizer.tokens(), "string {");
ASSERT(s1 && !s1->isIncompleteVar());
const Token* s2 = Token::findsimplematch(s1, "string (");
ASSERT(s2 && !s2->isIncompleteVar());
{
GET_SYMBOL_DB("void f() {\n"
" auto s1 = std::string{ \"abc\" };\n"
" auto s2 = std::string(\"def\");\n"
"}\n");
ASSERT(db && errout.str().empty());
const Token* s1 = Token::findsimplematch(tokenizer.tokens(), "string {");
ASSERT(s1 && !s1->isIncompleteVar());
const Token* s2 = Token::findsimplematch(s1, "string (");
ASSERT(s2 && !s2->isIncompleteVar());
}
{
GET_SYMBOL_DB("std::string f(int n, std::type_info t) {\n"
" std::vector<std::string*> v(n);\n"
" g<const std::string &>();\n"
" if (static_cast<int>(x)) {}\n"
" if (t == typeid(std::string)) {}\n"
" return (std::string) \"abc\";\n"
"}\n");
ASSERT(db && errout.str().empty());
const Token* s1 = Token::findsimplematch(tokenizer.tokens(), "string *");
ASSERT(s1 && !s1->isIncompleteVar());
const Token* s2 = Token::findsimplematch(s1, "string &");
ASSERT(s2 && !s2->isIncompleteVar());
const Token* x = Token::findsimplematch(s2, "x");
ASSERT(x && x->isIncompleteVar());
const Token* s3 = Token::findsimplematch(x, "string )");
ASSERT(s3 && !s3->isIncompleteVar());
const Token* s4 = Token::findsimplematch(s3->next(), "string )");
ASSERT(s4 && !s4->isIncompleteVar());
}
}
void enum1() {