Fix issue 10092: false positive: (warning) The address of local variable 'data' might be accessed at non-zero index. (#3041)
This commit is contained in:
parent
348b2d4832
commit
fc4238829f
|
@ -33,11 +33,12 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "valueflow.h"
|
#include "valueflow.h"
|
||||||
|
|
||||||
#include <tinyxml2.h>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <iterator>
|
||||||
#include <numeric> // std::accumulate
|
#include <numeric> // std::accumulate
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <tinyxml2.h>
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -886,6 +887,12 @@ void CheckBufferOverrun::objectIndex()
|
||||||
const Token *idx = tok->astOperand2();
|
const Token *idx = tok->astOperand2();
|
||||||
if (!idx || !obj)
|
if (!idx || !obj)
|
||||||
continue;
|
continue;
|
||||||
|
const ValueFlow::Value* vidx = nullptr;
|
||||||
|
if (idx->hasKnownIntValue()) {
|
||||||
|
if (idx->getKnownIntValue() == 0)
|
||||||
|
continue;
|
||||||
|
vidx = &idx->values().front();
|
||||||
|
}
|
||||||
if (idx->hasKnownIntValue() && idx->getKnownIntValue() == 0)
|
if (idx->hasKnownIntValue() && idx->getKnownIntValue() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -908,8 +915,28 @@ void CheckBufferOverrun::objectIndex()
|
||||||
if (var->valueType()->pointer > obj->valueType()->pointer)
|
if (var->valueType()->pointer > obj->valueType()->pointer)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (v.path != 0) {
|
||||||
|
std::vector<ValueFlow::Value> idxValues;
|
||||||
|
std::copy_if(idx->values().begin(),
|
||||||
|
idx->values().end(),
|
||||||
|
std::back_inserter(idxValues),
|
||||||
|
[&](const ValueFlow::Value& vidx) {
|
||||||
|
if (!vidx.isIntValue())
|
||||||
|
return false;
|
||||||
|
return vidx.path == v.path || vidx.path == 0;
|
||||||
|
});
|
||||||
|
if (idxValues.empty() ||
|
||||||
|
std::any_of(idxValues.begin(), idxValues.end(), [&](const ValueFlow::Value& vidx) {
|
||||||
|
if (vidx.isImpossible())
|
||||||
|
return (vidx.intvalue == 0);
|
||||||
|
else
|
||||||
|
return (vidx.intvalue != 0);
|
||||||
|
})) {
|
||||||
objectIndexError(tok, &v, idx->hasKnownIntValue());
|
objectIndexError(tok, &v, idx->hasKnownIntValue());
|
||||||
break;
|
}
|
||||||
|
} else {
|
||||||
|
objectIndexError(tok, &v, idx->hasKnownIntValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4496,6 +4496,17 @@ private:
|
||||||
" printf(\"%c\",*test[i]);\n"
|
" printf(\"%c\",*test[i]);\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:4] -> [test.cpp:9]: (warning) The address of local variable 'test' might be accessed at non-zero index.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:4] -> [test.cpp:9]: (warning) The address of local variable 'test' might be accessed at non-zero index.\n", errout.str());
|
||||||
|
|
||||||
|
check("void Bar(uint8_t data);\n"
|
||||||
|
"void Foo(const uint8_t * const data, const uint8_t length) {\n"
|
||||||
|
" for(uint8_t index = 0U; index < length ; ++index)\n"
|
||||||
|
" Bar(data[index]);\n"
|
||||||
|
"}\n"
|
||||||
|
"void test() {\n"
|
||||||
|
" const uint8_t data = 0U;\n"
|
||||||
|
" Foo(&data,1U);\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue