Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/checkbufferoverrun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok, cons
}
}

if (!var || var->isPointer() || (astIsContainer(bufTok) && var->getTypeName() != "std::array"))
if (!var || var->isPointer() || (astIsContainer(bufTok) && !var->isStlType("array")))
return ValueFlow::Value(-1);

const MathLib::bigint dim = std::accumulate(var->dimensions().cbegin(), var->dimensions().cend(), MathLib::bigint(1), [](MathLib::bigint i1, const Dimension &dim) {
Expand Down
13 changes: 2 additions & 11 deletions lib/checkclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ bool CheckClassImpl::isInitialized(const Usage& usage, FunctionType funcType) co
{
// needs initialization
}
else if (var.getTypeName() == "std::array") {
else if (var.isStlType("array")) {
const Token* ctt = var.valueType()->containerTypeToken;
if (!ctt->isStandardType() &&
(!ctt->type() || ctt->type()->needInitialization != Type::NeedInitialization::True) &&
Expand Down Expand Up @@ -1577,18 +1577,9 @@ void CheckClassImpl::checkMemsetType(const Scope *start, const Token *tok, const
}
// don't warn if variable static or const, pointer or array of pointers
if (!var.isStatic() && !var.isConst() && !var.isPointer() && (!var.isArray() || var.typeEndToken()->str() != "*")) {
const Token *tok1 = var.typeStartToken();
const Scope *typeScope = var.typeScope();

std::string typeName;
if (Token::Match(tok1, "%type% ::")) {
const Token *typeTok = tok1;
while (Token::Match(typeTok, "%type% ::")) {
typeName += typeTok->str() + "::";
typeTok = typeTok->tokAt(2);
}
typeName += typeTok->str();
}
const std::string typeName = var.getTypeName();

// check for std:: type
if (var.isStlType() && typeName != "std::array" && !mSettings.library.podtype(typeName)) {
Expand Down
2 changes: 1 addition & 1 deletion lib/checksizeof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void CheckSizeofImpl::checkSizeofForArrayParameter()
}

const Variable *var = varTok->variable();
if (var && var->isArray() && var->isArgument() && !var->isReference() && !(var->isStlType() && var->getTypeName() == "std::array"))
if (var && var->isArray() && var->isArgument() && !var->isReference() && !var->isStlType("array"))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an AI review take it with a grain of salt. Please feel free to reject it by clicking on Resolve

Same isStlType("array") vs getTypeName() == "std::array" difference as in valueflow.cpp. This one causes a false negative:

int g6(std::array<int,3>::value_type a[2]) { return sizeof(a); }

main warns sizeofwithsilentarraypointer, the PR is silent. (The old code here had both isStlType() and getTypeName() == "std::array", so it was exact.)

sizeofForArrayParameterError(tok);
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ static void valueFlowArrayBool(TokenList& tokenlist, const Settings& settings)
}
if (!var)
continue;
if (!var->isArray() || var->isArgument() || var->getTypeName() == "std::array")
if (!var->isArray() || var->isArgument() || var->isStlType("array"))
continue;
if (isNonZero(getOtherOperand(tok)) && Token::Match(tok->astParent(), "%comp%"))
continue;
Expand Down Expand Up @@ -1169,7 +1169,7 @@ static void valueFlowImpossibleValues(TokenList& tokenList, const Settings& sett
value.setImpossible();
setTokenValue(tok, std::move(value), settings);
} else if (tok->variable() && tok->variable()->isArray() && !tok->variable()->isArgument() &&
tok->variable()->getTypeName() != "std::array") {
!tok->variable()->isStlType("array")) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an AI review take it with a grain of salt. Please feel free to reject it by clicking on Resolve

isStlType("array") is not exactly equivalent to the old getTypeName() == "std::array". It only checks typeStartToken()->strAt(2), so nested types such as std::array<int,3>::value_type are now treated as std::array too. I compared main and this PR:

void h1() { std::array<int,3>::value_type a[2] = {}; if (a) {} }
void h2() { std::array<int,3>::value_type a[2] = {}; if (a == nullptr) {} }

main: knownConditionTrueFalse on both (correct, it is a plain int[2]).
PR: no knownConditionTrueFalse, but instead a new FP nullPointerRedundantCheck: Either the condition 'a' is redundant or there is possible null pointer dereference on both lines.

The same applies to valueFlowArrayBool() (line 730). It is admittedly an unusual way to write code, and the warnings on lib/, cli/, test/cfg/ and samples/ are identical, so it is minor. But it could be avoided by keeping getTypeName() == "std::array" in the places that only did a rename, or by making Variable::isStlType(const std::string&) reject a type that continues with :: after the template arguments.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danmar: Do you see what's happening here? First, there is a suggestion, and only after adopting it I'm told it's a bad idea. What a waste of time.

ValueFlow::Value value{0};
value.setImpossible();
setTokenValue(tok, std::move(value), settings);
Expand Down Expand Up @@ -5995,7 +5995,7 @@ static bool needsInitialization(const Variable* var)
return true;
if (var->valueType()->type == ValueType::Type::ITERATOR)
return true;
if (var->isStlType() && var->isArray()) {
if (var->isArray() && var->isStlType("array")) {
if (const Token* ctt = var->valueType()->containerTypeToken) {
if (ctt->isStandardType())
return true;
Expand Down
6 changes: 6 additions & 0 deletions test/testuninitvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6788,6 +6788,12 @@ class TestUninitVar : public TestFixture {
" return a[0];\n"
"}\n");
ASSERT_EQUALS("", errout_str());

valueFlowUninit("std::vector<int> f() {\n" // #15077
" const std::vector<int> a[1];\n"
" return a[0];\n"
"}\n");
ASSERT_EQUALS("", errout_str());
}

void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value
Expand Down
Loading