Fix issue 10147: False positive: Out of bounds access in expression 'v[0]' because 'v' is empty. (#3123)
This commit is contained in:
parent
ff125f6ac6
commit
8569a970b4
|
@ -403,6 +403,20 @@ void execute(const Token *expr,
|
||||||
*error = true;
|
*error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (Token::Match(expr->tokAt(-3), "%var% . %name% (") && astIsContainer(expr->tokAt(-3))) {
|
||||||
|
const Token* containerTok = expr->tokAt(-3);
|
||||||
|
Library::Container::Yield yield = containerTok->valueType()->container->getYield(expr->strAt(-1));
|
||||||
|
if (yield == Library::Container::Yield::SIZE) {
|
||||||
|
if (!programMemory->getContainerSizeValue(containerTok->exprId(), result))
|
||||||
|
*error = true;
|
||||||
|
} else if (yield == Library::Container::Yield::EMPTY) {
|
||||||
|
if (!programMemory->getContainerEmptyValue(containerTok->exprId(), result))
|
||||||
|
*error = true;
|
||||||
|
} else {
|
||||||
|
*error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else if (expr->exprId() > 0 && programMemory->hasValue(expr->exprId())) {
|
else if (expr->exprId() > 0 && programMemory->hasValue(expr->exprId())) {
|
||||||
if (!programMemory->getIntValue(expr->exprId(), result))
|
if (!programMemory->getIntValue(expr->exprId(), result))
|
||||||
*error = true;
|
*error = true;
|
||||||
|
@ -570,24 +584,7 @@ void execute(const Token *expr,
|
||||||
*result = 0;
|
*result = 0;
|
||||||
else
|
else
|
||||||
*error = true;
|
*error = true;
|
||||||
} else if (Token::Match(expr->tokAt(-3), "%var% . %name% (")) {
|
|
||||||
const Token* containerTok = expr->tokAt(-3);
|
|
||||||
if (astIsContainer(containerTok)) {
|
|
||||||
Library::Container::Yield yield = containerTok->valueType()->container->getYield(expr->strAt(-1));
|
|
||||||
if (yield == Library::Container::Yield::SIZE) {
|
|
||||||
if (!programMemory->getContainerSizeValue(containerTok->exprId(), result))
|
|
||||||
*error = true;
|
|
||||||
} else if (yield == Library::Container::Yield::EMPTY) {
|
|
||||||
if (!programMemory->getContainerEmptyValue(containerTok->exprId(), result))
|
|
||||||
*error = true;
|
|
||||||
} else {
|
|
||||||
*error = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*error = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
*error = true;
|
*error = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5069,6 +5069,18 @@ private:
|
||||||
" return a.size();\n"
|
" return a.size();\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ASSERT_EQUALS(true, tokenValues(code, "a . size", ValueFlow::Value::ValueType::CONTAINER_SIZE).empty());
|
ASSERT_EQUALS(true, tokenValues(code, "a . size", ValueFlow::Value::ValueType::CONTAINER_SIZE).empty());
|
||||||
|
|
||||||
|
code = "std::vector<int> g();\n"
|
||||||
|
"std::vector<int> f() {\n"
|
||||||
|
" std::vector<int> v = g();\n"
|
||||||
|
" if (!v.empty()) {\n"
|
||||||
|
" if (v[0] != 0)\n"
|
||||||
|
" v.clear();\n"
|
||||||
|
" }\n"
|
||||||
|
" if (!v.empty() && v[0] != 0) {}\n"
|
||||||
|
" return v;\n"
|
||||||
|
"}\n";
|
||||||
|
ASSERT_EQUALS(true, tokenValues(code, "v [ 0 ] != 0 ) { }", ValueFlow::Value::ValueType::CONTAINER_SIZE).empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void valueFlowDynamicBufferSize() {
|
void valueFlowDynamicBufferSize() {
|
||||||
|
|
Loading…
Reference in New Issue