Fixed #10222 (regression: arrayIndexOutOfBounds)

This commit is contained in:
Daniel Marjamäki 2021-11-03 20:16:44 +01:00
parent d3f0aa5b34
commit 0f259a5dc6
2 changed files with 43 additions and 3 deletions

View File

@ -3394,10 +3394,22 @@ static const Token* getEndOfVarScope(const Token* tok, const std::vector<const V
{
const Token* endOfVarScope = nullptr;
for (const Variable* var : vars) {
const Scope *varScope = nullptr;
if (var && (var->isLocal() || var->isArgument()) && var->typeStartToken()->scope()->type != Scope::eNamespace)
endOfVarScope = var->typeStartToken()->scope()->bodyEnd;
else if (!endOfVarScope)
endOfVarScope = tok->scope()->bodyEnd;
varScope = var->typeStartToken()->scope();
else if (!endOfVarScope) {
varScope = tok->scope();
// A "local member" will be a expression like foo.x where foo is a local variable.
// A "global member" will be a member that belongs to a global object.
const bool globalMember = vars.size() == 1; // <- could check if it's a member here also but it seems redundant
if (var && (var->isGlobal() || var->isNamespace() || globalMember)) {
// Global variable => end of function
while (varScope->isLocal())
varScope = varScope->nestedIn;
}
}
if (varScope && (!endOfVarScope || precedes(varScope->bodyEnd, endOfVarScope)))
endOfVarScope = varScope->bodyEnd;
}
return endOfVarScope;
}

View File

@ -2475,6 +2475,34 @@ private:
" }\n"
"};\n";
ASSERT_EQUALS(true, testValueOfXKnown(code, 7U, 1));
// global variable
code = "int x;\n"
"int foo(int y) {\n"
" if (y)\n"
" x = 10;\n"
" return x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 5U, 10));
code = "namespace A { int x; }\n"
"int foo(int y) {\n"
" if (y)\n"
" A::x = 10;\n"
" return A::x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 5U, 10));
// member variable
code = "struct Fred {\n"
" int x;\n"
" int foo(int y) {\n"
" if (y)\n"
" x = 10;\n"
" return x;\n"
" }\n"
"};";
ASSERT_EQUALS(true, testValueOfX(code, 6U, 10));
}
void valueFlowAfterSwap()