Fixed #4751 (CheckBufferOverrun: better handling when struct member instance doesn't have same varid as struct member declaration)
This commit is contained in:
parent
ae7363fe54
commit
a861817a01
|
@ -1384,7 +1384,7 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
|
|||
for (unsigned int i = 1; i <= _tokenizer->varIdCount(); i++) {
|
||||
const Variable *var = symbolDatabase->getVariableFromVarId(i);
|
||||
if (var && var->isArray() && var->dimension(0) > 0) {
|
||||
const ArrayInfo arrayInfo(var, _tokenizer);
|
||||
const ArrayInfo arrayInfo(var, _tokenizer, i);
|
||||
const Token *tok = var->nameToken();
|
||||
while (tok && tok->str() != ";") {
|
||||
if (tok->str() == "{") {
|
||||
|
@ -1972,8 +1972,8 @@ CheckBufferOverrun::ArrayInfo::ArrayInfo(const CheckBufferOverrun::ArrayInfo &ai
|
|||
*this = ai;
|
||||
}
|
||||
|
||||
CheckBufferOverrun::ArrayInfo::ArrayInfo(const Variable *var, const Tokenizer *tokenizer)
|
||||
: _varname(var->name()), _varid(var->varId())
|
||||
CheckBufferOverrun::ArrayInfo::ArrayInfo(const Variable *var, const Tokenizer *tokenizer, const unsigned int forcevarid)
|
||||
: _varname(var->name()), _varid((forcevarid == 0U) ? var->varId() : forcevarid)
|
||||
{
|
||||
for (std::size_t i = 0; i < var->dimensions().size(); i++)
|
||||
_num.push_back(var->dimension(i));
|
||||
|
|
|
@ -131,7 +131,7 @@ public:
|
|||
public:
|
||||
ArrayInfo();
|
||||
ArrayInfo(const ArrayInfo &);
|
||||
ArrayInfo(const Variable *var, const Tokenizer *tokenizer);
|
||||
ArrayInfo(const Variable *var, const Tokenizer *tokenizer, const unsigned int forcevarid = 0);
|
||||
ArrayInfo & operator=(const ArrayInfo &ai);
|
||||
|
||||
/**
|
||||
|
|
|
@ -140,6 +140,7 @@ private:
|
|||
TEST_CASE(array_index_extern); // FP when using 'extern'. #1684
|
||||
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(buffer_overrun_1_standard_functions);
|
||||
TEST_CASE(buffer_overrun_2_struct);
|
||||
|
@ -1991,6 +1992,30 @@ private:
|
|||
|
||||
}
|
||||
|
||||
void array_index_same_struct_and_var_name() {
|
||||
// don't throw internal error
|
||||
check("struct tt {\n"
|
||||
" char typename[21];\n"
|
||||
"} ;\n"
|
||||
"void doswitch(struct tt *x)\n"
|
||||
"{\n"
|
||||
" struct tt *tt=x;\n"
|
||||
" tt->typename;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// detect error
|
||||
check("struct tt {\n"
|
||||
" char typename[21];\n"
|
||||
"} ;\n"
|
||||
"void doswitch(struct tt *x)\n"
|
||||
"{\n"
|
||||
" struct tt *tt=x;\n"
|
||||
" tt->typename[22] = 123;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (error) Array 'tt.typename[21]' accessed at index 22, which is out of bounds.\n", errout.str());
|
||||
}
|
||||
|
||||
void buffer_overrun_1_standard_functions() {
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
|
|
Loading…
Reference in New Issue