From 56924643bebd6ce6c93f8918e50bc28fca71b925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 8 Jul 2021 18:18:32 +0200 Subject: [PATCH] Fixed #10347 (ValueFlow: No known value set for sizeof(a[0])) --- lib/valueflow.cpp | 12 ++++++++++++ test/testvalueflow.cpp | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index f081046fc..988923287 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -999,6 +999,18 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b value.setKnown(); setTokenValue(tok, value, settings); } else if (Token::simpleMatch(tok, "sizeof (")) { + if (tok->next()->astOperand2() && !tok->next()->astOperand2()->isLiteral() && tok->next()->astOperand2()->valueType() && + tok->next()->astOperand2()->valueType()->pointer == 0 && // <- TODO this is a bailout, abort when there are array->pointer conversions + !tok->next()->astOperand2()->valueType()->isEnum()) { // <- TODO this is a bailout, handle enum with non-int types + const size_t sz = ValueFlow::getSizeOf(*tok->next()->astOperand2()->valueType(), settings); + if (sz) { + ValueFlow::Value value(sz); + value.setKnown(); + setTokenValue(tok->next(), value, settings); + return tok->linkAt(1); + } + } + const Token *tok2 = tok->tokAt(2); // skip over tokens to find variable or type while (Token::Match(tok2, "%name% ::|.|[")) { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 295b3a73e..2f21796f1 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -907,6 +907,14 @@ private: ASSERT_EQUALS(1U, values.size()); ASSERT_EQUALS(1, values.back().intvalue); + code = "void f() {\n" + " char a[10];" + " x = sizeof(a[0]);\n" + "}"; + values = tokenValues(code,"( a"); + ASSERT_EQUALS(1U, values.size()); + ASSERT_EQUALS(1, values.back().intvalue); + code = "enum testEnum : uint32_t { a };\n" "sizeof(testEnum);"; values = tokenValues(code,"( testEnum");