Fixed #10222 (regression: arrayIndexOutOfBounds)
This commit is contained in:
parent
d3f0aa5b34
commit
0f259a5dc6
|
@ -3394,10 +3394,22 @@ static const Token* getEndOfVarScope(const Token* tok, const std::vector<const V
|
||||||
{
|
{
|
||||||
const Token* endOfVarScope = nullptr;
|
const Token* endOfVarScope = nullptr;
|
||||||
for (const Variable* var : vars) {
|
for (const Variable* var : vars) {
|
||||||
|
const Scope *varScope = nullptr;
|
||||||
if (var && (var->isLocal() || var->isArgument()) && var->typeStartToken()->scope()->type != Scope::eNamespace)
|
if (var && (var->isLocal() || var->isArgument()) && var->typeStartToken()->scope()->type != Scope::eNamespace)
|
||||||
endOfVarScope = var->typeStartToken()->scope()->bodyEnd;
|
varScope = var->typeStartToken()->scope();
|
||||||
else if (!endOfVarScope)
|
else if (!endOfVarScope) {
|
||||||
endOfVarScope = tok->scope()->bodyEnd;
|
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;
|
return endOfVarScope;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2475,6 +2475,34 @@ private:
|
||||||
" }\n"
|
" }\n"
|
||||||
"};\n";
|
"};\n";
|
||||||
ASSERT_EQUALS(true, testValueOfXKnown(code, 7U, 1));
|
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()
|
void valueFlowAfterSwap()
|
||||||
|
|
Loading…
Reference in New Issue