diff --git a/lib/checksizeof.cpp b/lib/checksizeof.cpp index daa08ee62..21a29f273 100644 --- a/lib/checksizeof.cpp +++ b/lib/checksizeof.cpp @@ -378,22 +378,16 @@ void CheckSizeof::suspiciousSizeofCalculation() const Token* lPar = tok->astParent(); if (lPar && lPar->str() == "(") { const Token* const rPar = lPar->link(); - const Token* varTok = rPar->previous(); - while (varTok && varTok->str() == "]") - varTok = varTok->link()->previous(); + const Token* varTok = lPar->astOperand2(); + int derefCount = 0; + while (Token::Match(varTok, "[|*")) { + ++derefCount; + varTok = varTok->astOperand1(); + } if (lPar->astParent() && lPar->astParent()->str() == "/") { const Variable* var = varTok ? varTok->variable() : nullptr; - if (var && var->isPointer() && !var->isArray() && !(lPar->astOperand2() && lPar->astOperand2()->str() == "*")) + if (var && var->isPointer() && !var->isArray() && !(var->valueType() && var->valueType()->pointer <= derefCount)) divideSizeofError(tok); - else if (varTok && varTok->str() == "*") { - const Token* arrTok = lPar->astParent()->astOperand1(); - arrTok = arrTok ? arrTok->astOperand2() : nullptr; - while (Token::simpleMatch(arrTok, ".")) - arrTok = arrTok->astOperand2(); - var = arrTok ? arrTok->variable() : nullptr; - if (var && var->isPointer() && !var->isArray()) - divideSizeofError(tok); - } } else if (Token::simpleMatch(rPar, ") * sizeof") && rPar->next()->astOperand1() == tok->next()) multiplySizeofError(tok); diff --git a/test/testsizeof.cpp b/test/testsizeof.cpp index d52380b4e..77e19f3dc 100644 --- a/test/testsizeof.cpp +++ b/test/testsizeof.cpp @@ -440,11 +440,10 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); - check("int f(const S& s) {\n" - " int** p;\n" + check("int f(int** p) {\n" " return sizeof(p[0]) / 4;\n" "}\n"); - ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Division of result of sizeof() on pointer type.\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Division of result of sizeof() on pointer type.\n", errout.str()); check("struct S {\n" " unsigned char* s;\n" @@ -466,6 +465,17 @@ private: " for (int i = 0; i != sizeof(s->t[0].c) / sizeof(char*); i++) {}\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("void f(int32_t* buf, size_t len) {\n" + " for (int i = 0; i < len / sizeof(buf[0]); i++) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f(int32_t*** buf, size_t len) {\n" + " for (int i = 0; i < len / sizeof(**buf[0]); i++) {}\n" + " for (int i = 0; i < len / sizeof(*buf[0][0]); i++) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void checkPointerSizeof() {