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

View File

@ -5432,15 +5432,37 @@ private:
void createSymbolDatabaseIncompleteVars() void createSymbolDatabaseIncompleteVars()
{ {
GET_SYMBOL_DB("void f() {\n" {
" auto s1 = std::string{ \"abc\" };\n" GET_SYMBOL_DB("void f() {\n"
" auto s2 = std::string(\"def\");\n" " auto s1 = std::string{ \"abc\" };\n"
"}\n"); " auto s2 = std::string(\"def\");\n"
ASSERT(db && errout.str().empty()); "}\n");
const Token* s1 = Token::findsimplematch(tokenizer.tokens(), "string {"); ASSERT(db && errout.str().empty());
ASSERT(s1 && !s1->isIncompleteVar()); const Token* s1 = Token::findsimplematch(tokenizer.tokens(), "string {");
const Token* s2 = Token::findsimplematch(s1, "string ("); ASSERT(s1 && !s1->isIncompleteVar());
ASSERT(s2 && !s2->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() { void enum1() {