ValueFlow: string can be constructed from init list (#3459)
This commit is contained in:
parent
5be950a4ff
commit
609e20d9d8
|
@ -203,6 +203,11 @@ bool astIsUnknownSignChar(const Token *tok)
|
||||||
return astIsCharWithSign(tok, ValueType::Sign::UNKNOWN_SIGN);
|
return astIsCharWithSign(tok, ValueType::Sign::UNKNOWN_SIGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool astIsGenericChar(const Token* tok)
|
||||||
|
{
|
||||||
|
return tok && tok->valueType() && (tok->valueType()->type == ValueType::Type::CHAR || tok->valueType()->type == ValueType::Type::WCHAR_T);
|
||||||
|
}
|
||||||
|
|
||||||
bool astIsIntegral(const Token *tok, bool unknown)
|
bool astIsIntegral(const Token *tok, bool unknown)
|
||||||
{
|
{
|
||||||
const ValueType *vt = tok ? tok->valueType() : nullptr;
|
const ValueType *vt = tok ? tok->valueType() : nullptr;
|
||||||
|
|
|
@ -67,6 +67,8 @@ bool astHasVar(const Token * tok, nonneg int varid);
|
||||||
bool astIsSignedChar(const Token *tok);
|
bool astIsSignedChar(const Token *tok);
|
||||||
/** Is expression a 'char' if no promotion is used? */
|
/** Is expression a 'char' if no promotion is used? */
|
||||||
bool astIsUnknownSignChar(const Token *tok);
|
bool astIsUnknownSignChar(const Token *tok);
|
||||||
|
/** Is expression a char according to valueType? */
|
||||||
|
bool astIsGenericChar(const Token* tok);
|
||||||
/** Is expression of integral type? */
|
/** Is expression of integral type? */
|
||||||
bool astIsIntegral(const Token *tok, bool unknown);
|
bool astIsIntegral(const Token *tok, bool unknown);
|
||||||
bool astIsUnsigned(const Token* tok);
|
bool astIsUnsigned(const Token* tok);
|
||||||
|
|
|
@ -7045,8 +7045,9 @@ static std::vector<ValueFlow::Value> getInitListSize(const Token* tok,
|
||||||
bool known = true)
|
bool known = true)
|
||||||
{
|
{
|
||||||
std::vector<const Token*> args = getArguments(tok);
|
std::vector<const Token*> args = getArguments(tok);
|
||||||
// Strings don't use an init list
|
|
||||||
if (!args.empty() && container->stdStringLike) {
|
if (!args.empty() && container->stdStringLike) {
|
||||||
|
if (astIsGenericChar(args[0])) // init list of chars
|
||||||
|
return { makeContainerSizeValue(args.size(), known) };
|
||||||
if (astIsIntegral(args[0], false)) {
|
if (astIsIntegral(args[0], false)) {
|
||||||
if (args.size() > 1)
|
if (args.size() > 1)
|
||||||
return {makeContainerSizeValue(args[0], known)};
|
return {makeContainerSizeValue(args[0], known)};
|
||||||
|
|
|
@ -5126,6 +5126,12 @@ private:
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "s . size"), 3));
|
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "s . size"), 3));
|
||||||
|
|
||||||
|
code = "void f() {\n"
|
||||||
|
" std::string s = { 'a', 'b', 'c' };\n" // size of s is 3
|
||||||
|
" s.size();\n"
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "s . size"), 3));
|
||||||
|
|
||||||
code = "void f() {\n"
|
code = "void f() {\n"
|
||||||
" std::string s=\"abc\";\n" // size of s is 3
|
" std::string s=\"abc\";\n" // size of s is 3
|
||||||
" s += unknown;\n"
|
" s += unknown;\n"
|
||||||
|
|
Loading…
Reference in New Issue