value flow: Use ValueFlow in CheckBufferOverrun

This commit is contained in:
Daniel Marjamäki 2014-01-16 19:23:14 +01:00
parent 45c9a63157
commit 0b4de97e2b
2 changed files with 41 additions and 0 deletions

View File

@ -1138,6 +1138,18 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
continue;
}
else if (Token::Match(tok, "%varid% [", arrayInfo.declarationId()) && tok->next()->astOperand2() && !tok->next()->astOperand2()->values.empty()) {
const std::list<ValueFlow::Value> &values = tok->next()->astOperand2()->values;
std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) {
if (it->intvalue >= arrayInfo.num()[0]) {
std::vector<MathLib::bigint> indexes;
indexes.push_back(it->intvalue);
arrayIndexOutOfBoundsError(tok, arrayInfo, indexes);
}
}
}
else if (Token::Match(tok, "%varid% [ %num% ]", arrayInfo.declarationId())) {
std::vector<MathLib::bigint> indexes;
for (const Token *tok2 = tok->next(); Token::Match(tok2, "[ %num% ]"); tok2 = tok2->tokAt(3)) {

View File

@ -72,6 +72,25 @@ private:
checkBufferOverrun.writeOutsideBufferSize();
}
void checkValueFlow(const char code[]) {
// Clear the error buffer..
errout.str("");
Settings settings;
settings.valueFlow = true;
settings.addEnabled("warning");
// Tokenize..
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList2();
// Check for buffer overruns..
CheckBufferOverrun checkBufferOverrun(&tokenizer, &settings, this);
checkBufferOverrun.bufferOverrun();
}
void run() {
TEST_CASE(noerr1);
TEST_CASE(noerr2);
@ -142,6 +161,7 @@ private:
TEST_CASE(array_index_cast); // FP after cast. #2841
TEST_CASE(array_index_string_literal);
TEST_CASE(array_index_same_struct_and_var_name); // #4751 - not handled well when struct name and var name is same
TEST_CASE(array_index_valueflow);
TEST_CASE(buffer_overrun_1_standard_functions);
TEST_CASE(buffer_overrun_2_struct);
@ -2050,6 +2070,15 @@ private:
ASSERT_EQUALS("[test.cpp:7]: (error) Array 'tt.name[21]' accessed at index 22, which is out of bounds.\n", errout.str());
}
void array_index_valueflow() {
checkValueFlow("void f(int i) {\n"
" char str[3];\n"
" str[i] = 0;\n"
" if (i==10) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'str[3]' accessed at index 10, which is out of bounds.\n", errout.str());
}
void buffer_overrun_1_standard_functions() {
check("void f()\n"
"{\n"