Partial fix for #10867 FN containerOutOfBounds with std::array (#3971)

* Partial fix for #10867 FN containerOutOfBounds with std::array

* Format

* Format

* Optimize
This commit is contained in:
chrchr-github 2022-04-05 07:34:20 +02:00 committed by GitHub
parent b79885c6af
commit cfbbeb4b1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 3 deletions

View File

@ -7632,7 +7632,10 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
// declaration
for (const Variable *var : symboldatabase->variableList()) {
bool known = true;
if (!var || !var->isLocal() || var->isPointer() || var->isReference() || var->isStatic())
if (!var || !var->isLocal() || var->isPointer() || var->isReference())
continue;
const bool hasFixedSize = Token::simpleMatch(var->typeStartToken(), "std :: array");
if (var->isStatic() && !hasFixedSize)
continue;
if (!var->valueType() || !var->valueType()->container)
continue;
@ -7643,7 +7646,7 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
continue;
const bool isDecl = Token::Match(vnt, "%name% ;");
bool hasInitList = false, hasInitSize = false, isPointerInit = false;
if (!isDecl) {
if (!isDecl && !hasFixedSize) {
hasInitList = Token::Match(vnt, "%name% {") && Token::simpleMatch(vnt->next()->link(), "} ;");
if (!hasInitList)
hasInitList = Token::Match(vnt, "%name% ( {") && Token::simpleMatch(vnt->linkAt(2), "} ) ;");
@ -7652,7 +7655,7 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
if (!hasInitList && !hasInitSize)
isPointerInit = Token::Match(vnt, "%name% ( %var% ,");
}
if (!isDecl && !hasInitList && !hasInitSize && !isPointerInit)
if (!isDecl && !hasInitList && !hasInitSize && !isPointerInit && !hasFixedSize)
continue;
if (vnt->astTop() && Token::Match(vnt->astTop()->previous(), "for|while"))
known = !isVariableChanged(var, settings, true);

View File

@ -787,6 +787,22 @@ private:
TODO_ASSERT_EQUALS("test.cpp:4:error:Out of bounds access in 'v[100]', if 'v' size is 3 and '100' is 100\n",
"",
errout.str());
check("void f() {\n"
" std::array<int, 10> a = {};\n"
" a[10];\n"
" constexpr std::array<int, 10> b = {};\n"
" b[10];\n"
" const std::array<int, 10> c = {};\n"
" c[10];\n"
" static constexpr std::array<int, 10> d = {};\n"
" d[10];\n"
"}\n");
ASSERT_EQUALS("test.cpp:3:error:Out of bounds access in 'a[10]', if 'a' size is 10 and '10' is 10\n"
"test.cpp:5:error:Out of bounds access in 'b[10]', if 'b' size is 10 and '10' is 10\n"
"test.cpp:7:error:Out of bounds access in 'c[10]', if 'c' size is 10 and '10' is 10\n"
"test.cpp:9:error:Out of bounds access in 'd[10]', if 'd' size is 10 and '10' is 10\n",
errout.str());
}
void outOfBoundsSymbolic()