Get type from auto (#4640)

This commit is contained in:
chrchr-github 2022-12-18 16:54:58 +01:00 committed by GitHub
parent b1abaf8809
commit 617cd29a41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 0 deletions

View File

@ -2255,6 +2255,7 @@ std::pair<const Token*, const Token*> Token::typeDecl(const Token* tok, bool poi
const Variable *var = tok->variable(); const Variable *var = tok->variable();
if (!var->typeStartToken() || !var->typeEndToken()) if (!var->typeStartToken() || !var->typeEndToken())
return {}; return {};
std::pair<const Token*, const Token*> result;
if (Token::simpleMatch(var->typeStartToken(), "auto")) { if (Token::simpleMatch(var->typeStartToken(), "auto")) {
const Token * tok2 = var->declEndToken(); const Token * tok2 = var->declEndToken();
if (Token::Match(tok2, "; %varid% =", var->declarationId())) if (Token::Match(tok2, "; %varid% =", var->declarationId()))
@ -2272,6 +2273,17 @@ std::pair<const Token*, const Token*> Token::typeDecl(const Token* tok, bool poi
declEnd = declEnd->link()->next(); declEnd = declEnd->link()->next();
return { tok2->next(), declEnd }; return { tok2->next(), declEnd };
} }
const Token *typeBeg{}, *typeEnd{};
if (tok2->str() == "::" && Token::simpleMatch(tok2->astOperand2(), "{")) { // empty initlist
typeBeg = previousBeforeAstLeftmostLeaf(tok2);
typeEnd = tok2->astOperand2();
}
else if (tok2->str() == "{") {
typeBeg = previousBeforeAstLeftmostLeaf(tok2);
typeEnd = tok2;
}
if (typeBeg)
result = { typeBeg->next(), typeEnd }; // handle smart pointers/iterators first
} }
if (astIsRangeBasedForDecl(var->nameToken()) && astIsContainer(var->nameToken()->astParent()->astOperand2())) { // range-based for if (astIsRangeBasedForDecl(var->nameToken()) && astIsContainer(var->nameToken()->astParent()->astOperand2())) { // range-based for
const ValueType* vt = var->nameToken()->astParent()->astOperand2()->valueType(); const ValueType* vt = var->nameToken()->astParent()->astOperand2()->valueType();
@ -2288,6 +2300,8 @@ std::pair<const Token*, const Token*> Token::typeDecl(const Token* tok, bool poi
if (vt && vt->containerTypeToken) if (vt && vt->containerTypeToken)
return { vt->containerTypeToken, vt->containerTypeToken->linkAt(-1) }; return { vt->containerTypeToken, vt->containerTypeToken->linkAt(-1) };
} }
if (result.first)
return result;
} }
return {var->typeStartToken(), var->typeEndToken()->next()}; return {var->typeStartToken(), var->typeEndToken()->next()};
} else if (Token::simpleMatch(tok, "return")) { } else if (Token::simpleMatch(tok, "return")) {

View File

@ -1928,6 +1928,29 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" auto v = std::vector<int>{};\n"
" v.push_back(1);\n"
" auto w = std::vector<int>{ 1, 2, 3 };\n"
" w.push_back(1);\n"
" auto x = std::vector<int>(1);\n"
" x.push_back(1);\n"
"}\n");
TODO_ASSERT_EQUALS("",
"[test.cpp:7]: (information) --check-library: There is no matching configuration for function auto::push_back()\n",
errout.str());
check("void f() {\n"
" auto p(std::make_shared<std::vector<int>>());\n"
" p->push_back(1);\n"
" auto q{ std::make_shared<std::vector<int>>{} };\n"
" q->push_back(1);\n"
"}\n");
TODO_ASSERT_EQUALS("",
"[test.cpp:3]: (information) --check-library: There is no matching configuration for function auto::push_back()\n"
"[test.cpp:5]: (information) --check-library: There is no matching configuration for function auto::push_back()\n",
errout.str());
settings.severity = severity_old; settings.severity = severity_old;
settings.checkLibrary = false; settings.checkLibrary = false;
} }