diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 7a0e5b9ac..1040bad69 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -875,9 +875,13 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo index = tok->astParent()->astOperand2(); else index = tok->astParent()->astOperand1(); - const ValueFlow::Value *value = index ? index->getMaxValue(false) : nullptr; - if (value && (value->intvalue < 0 || value->intvalue > arrayInfo.num(0))) - pointerOutOfBoundsError(tok->astParent(), index, value->intvalue); + if (index) { + const ValueFlow::Value *value = index->getValueGE(arrayInfo.num(0) + 1U, _settings); + if (!value) + value = index->getValueLE(-1, _settings); + if (value) + pointerOutOfBoundsError(tok->astParent(), index, value->intvalue); + } } else if (isPortabilityEnabled && tok->astParent() && tok->astParent()->str() == "-") { @@ -885,6 +889,8 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo if (var && var->isArray()) { const Token *index = tok->astParent()->astOperand2(); const ValueFlow::Value *value = index ? index->getValueGE(1,_settings) : nullptr; + if (!value) + value = index->getValueLE(-1 - arrayInfo.num(0), _settings); if (value) pointerOutOfBoundsError(tok->astParent(), index, value->intvalue); } diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index f0098165e..cbaaa336e 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -2970,6 +2970,13 @@ private: "}"); ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 'a+100' is out of bounds.\n", errout.str()); + check("void f(int i) {\n" + " char x[10];\n" + " if (i == 123) {}\n" + " dostuff(x+i);\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (portability) Undefined behaviour, when 'i' is 123 the pointer arithmetic 'x+i' is out of bounds.\n", errout.str()); + check("void f() {\n" // #6350 - fp when there is cast of buffer " wchar_t buf[64];\n" " p = (unsigned char *) buf + sizeof (buf);\n" @@ -3018,6 +3025,20 @@ private: " return x-1;\n" "}"); ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 'x-1' is out of bounds.\n", errout.str()); + + check("void f(int i) {\n" + " char x[10];\n" + " if (i == 123) {}\n" + " dostuff(x-i);\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (portability) Undefined behaviour, when 'i' is 123 the pointer arithmetic 'x-i' is out of bounds.\n", errout.str()); + + check("void f(int i) {\n" + " char x[10];\n" + " if (i == -20) {}\n" + " dostuff(x-i);\n" + "}"); + ASSERT_EQUALS("[test.cpp:4]: (portability) Undefined behaviour, when 'i' is -20 the pointer arithmetic 'x-i' is out of bounds.\n", errout.str()); } void sprintf1() {