diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 6878db264..d32701112 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -203,6 +203,11 @@ bool astIsUnknownSignChar(const Token *tok) 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) { const ValueType *vt = tok ? tok->valueType() : nullptr; diff --git a/lib/astutils.h b/lib/astutils.h index 452c9092e..87102f9be 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -67,6 +67,8 @@ bool astHasVar(const Token * tok, nonneg int varid); bool astIsSignedChar(const Token *tok); /** Is expression a 'char' if no promotion is used? */ bool astIsUnknownSignChar(const Token *tok); +/** Is expression a char according to valueType? */ +bool astIsGenericChar(const Token* tok); /** Is expression of integral type? */ bool astIsIntegral(const Token *tok, bool unknown); bool astIsUnsigned(const Token* tok); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 585c7a6ea..90668cd09 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -7045,8 +7045,9 @@ static std::vector getInitListSize(const Token* tok, bool known = true) { std::vector args = getArguments(tok); - // Strings don't use an init list if (!args.empty() && container->stdStringLike) { + if (astIsGenericChar(args[0])) // init list of chars + return { makeContainerSizeValue(args.size(), known) }; if (astIsIntegral(args[0], false)) { if (args.size() > 1) return {makeContainerSizeValue(args[0], known)}; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 61c9c71c8..12366df42 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -5126,6 +5126,12 @@ private: "}"; 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" " std::string s=\"abc\";\n" // size of s is 3 " s += unknown;\n"