From f70a8b2aca5c5df45d8efae191d1a23e091aa0fb Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 17 Jun 2026 09:48:13 +0200 Subject: [PATCH 1/4] Update checkbufferoverrun.cpp --- lib/checkbufferoverrun.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index d278208fcc3..17d4afbbeb7 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -558,7 +558,14 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) cons return ValueFlow::Value(-1); if (bufTok->isUnaryOp("&")) bufTok = bufTok->astOperand1(); - const Variable *var = bufTok->variable(); + const Token* varTok = bufTok; + if (Token::simpleMatch(bufTok, "[")) { + const Token* index = bufTok->astOperand2(); + if (!(index && index->hasKnownIntValue() && index->getKnownIntValue() == 0)) + return ValueFlow::Value(-1); + varTok = varTok->astOperand1(); + } + const Variable *var = varTok->variable(); if (!var || var->dimensions().empty()) { const ValueFlow::Value *value = getBufferSizeValue(bufTok); From 4233c6cf22247cbc11a2c50f56342b27f167f9b5 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 17 Jun 2026 09:51:31 +0200 Subject: [PATCH 2/4] Update testbufferoverrun.cpp --- test/testbufferoverrun.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index 23e55748ce6..1a03ca336f8 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -227,6 +227,7 @@ class TestBufferOverrun : public TestFixture { TEST_CASE(buffer_overrun_35); //#2304 TEST_CASE(buffer_overrun_36); TEST_CASE(buffer_overrun_37); + TEST_CASE(buffer_overrun_38); TEST_CASE(buffer_overrun_errorpath); TEST_CASE(buffer_overrun_bailoutIfSwitch); // ticket #2378 : bailoutIfSwitch TEST_CASE(buffer_overrun_function_array_argument); @@ -3507,6 +3508,39 @@ class TestBufferOverrun : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void buffer_overrun_38() { // #9173 + check("void f() {\n" + " int a[10];\n" + " memset(&a[0], 0, 20 * sizeof(int));\n" + "}\n" + "void g() {\n" + " int a[10];\n" + " memset(&a[0], 0, 10 * sizeof(int));\n" + "}\n" + "void h() {\n" + " int a[10];\n" + " memset(&a[5], 0, 5 * sizeof(int));\n" + "}\n" + "void i() {\n" + " int a[10][10];\n" + " memset(&a[0][0], 0, 100 * sizeof(int));\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &a[0] [bufferAccessOutOfBounds]\n", errout_str()); + + check("void f() {\n" + " int a[10];\n" + " memset(&a[5], 0, 10 * sizeof(int));\n" + "}\n" + "void g() {\n" + " int a[1][1];\n" + " memset(&a[0][0], 0, 10 * sizeof(int));\n" + "}\n"); + TODO_ASSERT_EQUALS("[test.cpp:3:12]: (error) Buffer is accessed out of bounds: &a[5] [bufferAccessOutOfBounds]\n" + "[test.cpp:7:12]: (error) Buffer is accessed out of bounds: &a[0][0] [bufferAccessOutOfBounds]\n", + "", + errout_str()); + } + void buffer_overrun_errorpath() { setMultiline(); Settings s = settings0; From b5bd7341ffbcb377f010b99b4b5418e57589d991 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 17 Jun 2026 09:57:26 +0200 Subject: [PATCH 3/4] Update checkbufferoverrun.cpp --- lib/checkbufferoverrun.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 17d4afbbeb7..53aa6a22658 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -556,14 +556,15 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) cons { if (!bufTok->valueType()) return ValueFlow::Value(-1); - if (bufTok->isUnaryOp("&")) - bufTok = bufTok->astOperand1(); const Token* varTok = bufTok; - if (Token::simpleMatch(bufTok, "[")) { - const Token* index = bufTok->astOperand2(); - if (!(index && index->hasKnownIntValue() && index->getKnownIntValue() == 0)) - return ValueFlow::Value(-1); - varTok = varTok->astOperand1(); + if (bufTok->isUnaryOp("&")) { + bufTok = bufTok->astOperand1(); + if (Token::simpleMatch(bufTok, "[")) { + const Token* index = bufTok->astOperand2(); + if (!(index && index->hasKnownIntValue() && index->getKnownIntValue() == 0)) + return ValueFlow::Value(-1); + varTok = bufTok->astOperand1(); + } } const Variable *var = varTok->variable(); From ca719a243f87bed2dad2b7aa2360872bcb53171d Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 17 Jun 2026 10:40:17 +0200 Subject: [PATCH 4/4] Update checkbufferoverrun.cpp --- lib/checkbufferoverrun.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 53aa6a22658..8be9b508849 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -556,17 +556,17 @@ ValueFlow::Value CheckBufferOverrunImpl::getBufferSize(const Token *bufTok) cons { if (!bufTok->valueType()) return ValueFlow::Value(-1); - const Token* varTok = bufTok; + if (bufTok->isUnaryOp("&")) { bufTok = bufTok->astOperand1(); if (Token::simpleMatch(bufTok, "[")) { const Token* index = bufTok->astOperand2(); if (!(index && index->hasKnownIntValue() && index->getKnownIntValue() == 0)) return ValueFlow::Value(-1); - varTok = bufTok->astOperand1(); + bufTok = bufTok->astOperand1(); } } - const Variable *var = varTok->variable(); + const Variable *var = bufTok->variable(); if (!var || var->dimensions().empty()) { const ValueFlow::Value *value = getBufferSizeValue(bufTok);