* Partial fix for #10867 FN containerOutOfBounds with std::array * Format * Format * Optimize
This commit is contained in:
parent
b79885c6af
commit
cfbbeb4b1b
|
@ -7632,7 +7632,10 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
|
||||||
// declaration
|
// declaration
|
||||||
for (const Variable *var : symboldatabase->variableList()) {
|
for (const Variable *var : symboldatabase->variableList()) {
|
||||||
bool known = true;
|
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;
|
continue;
|
||||||
if (!var->valueType() || !var->valueType()->container)
|
if (!var->valueType() || !var->valueType()->container)
|
||||||
continue;
|
continue;
|
||||||
|
@ -7643,7 +7646,7 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
|
||||||
continue;
|
continue;
|
||||||
const bool isDecl = Token::Match(vnt, "%name% ;");
|
const bool isDecl = Token::Match(vnt, "%name% ;");
|
||||||
bool hasInitList = false, hasInitSize = false, isPointerInit = false;
|
bool hasInitList = false, hasInitSize = false, isPointerInit = false;
|
||||||
if (!isDecl) {
|
if (!isDecl && !hasFixedSize) {
|
||||||
hasInitList = Token::Match(vnt, "%name% {") && Token::simpleMatch(vnt->next()->link(), "} ;");
|
hasInitList = Token::Match(vnt, "%name% {") && Token::simpleMatch(vnt->next()->link(), "} ;");
|
||||||
if (!hasInitList)
|
if (!hasInitList)
|
||||||
hasInitList = Token::Match(vnt, "%name% ( {") && Token::simpleMatch(vnt->linkAt(2), "} ) ;");
|
hasInitList = Token::Match(vnt, "%name% ( {") && Token::simpleMatch(vnt->linkAt(2), "} ) ;");
|
||||||
|
@ -7652,7 +7655,7 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
|
||||||
if (!hasInitList && !hasInitSize)
|
if (!hasInitList && !hasInitSize)
|
||||||
isPointerInit = Token::Match(vnt, "%name% ( %var% ,");
|
isPointerInit = Token::Match(vnt, "%name% ( %var% ,");
|
||||||
}
|
}
|
||||||
if (!isDecl && !hasInitList && !hasInitSize && !isPointerInit)
|
if (!isDecl && !hasInitList && !hasInitSize && !isPointerInit && !hasFixedSize)
|
||||||
continue;
|
continue;
|
||||||
if (vnt->astTop() && Token::Match(vnt->astTop()->previous(), "for|while"))
|
if (vnt->astTop() && Token::Match(vnt->astTop()->previous(), "for|while"))
|
||||||
known = !isVariableChanged(var, settings, true);
|
known = !isVariableChanged(var, settings, true);
|
||||||
|
|
|
@ -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",
|
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());
|
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()
|
void outOfBoundsSymbolic()
|
||||||
|
|
Loading…
Reference in New Issue