From f93cf9d1b7664ec7d1998d030688f33f5685402b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 16 Sep 2014 17:21:17 +0200 Subject: [PATCH] Fixed #6170 (Tokenizer: sizeof on array in 2d-array is not handled properly) --- lib/tokenize.cpp | 26 +++++++++++++++++++------- test/testsimplifytokens.cpp | 27 ++++++++++++--------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index b054e8cbb..623b78a7e 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -2935,6 +2935,7 @@ bool Tokenizer::simplifySizeof() { // Locate variable declarations and calculate the size std::map sizeOfVar; + std::map declTokOfVar; for (Token *tok = list.front(); tok; tok = tok->next()) { if (tok->varId() != 0 && sizeOfVar.find(tok->varId()) == sizeOfVar.end()) { const unsigned int varId = tok->varId(); @@ -2948,15 +2949,17 @@ bool Tokenizer::simplifySizeof() } sizeOfVar[varId] = size; + declTokOfVar[varId] = tok; } - else if (Token::Match(tok->previous(), "%type% %var% [ %num% ] [;=]") || - Token::Match(tok->tokAt(-2), "%type% * %var% [ %num% ] [;=]")) { + else if (Token::Match(tok->previous(), "%type% %var% [ %num% ] [[;=]") || + Token::Match(tok->tokAt(-2), "%type% * %var% [ %num% ] [[;=]")) { const unsigned int size = sizeOfType(tok->previous()); if (size == 0) continue; sizeOfVar[varId] = size * static_cast(MathLib::toLongNumber(tok->strAt(2))); + declTokOfVar[varId] = tok; } else if (Token::Match(tok->previous(), "%type% %var% [ %num% ] [,)]") || @@ -2964,6 +2967,7 @@ bool Tokenizer::simplifySizeof() Token tempTok(0); tempTok.str("*"); sizeOfVar[varId] = sizeOfType(&tempTok); + declTokOfVar[varId] = tok; } } } @@ -3131,16 +3135,24 @@ bool Tokenizer::simplifySizeof() std::size_t sz = 0; const unsigned int varid = tok->tokAt((tok->strAt(2) == "*") ? 3 : 2)->varId(); - if (varid != 0) { + if ((varid != 0) && (declTokOfVar.find(varid) != declTokOfVar.end())) { // Try to locate variable declaration.. - const Token *decltok = Token::findmatch(list.front(), "%varid%", varid); - if (Token::Match(decltok->previous(), "%type% %var% [")) { - sz = sizeOfType(decltok->previous()); - } else if (Token::Match(decltok->previous(), "* %var% [")) { + const Token *decltok = declTokOfVar[varid]; + if (Token::Match(decltok->previous(), "%type%|* %var% [")) { sz = sizeOfType(decltok->previous()); } else if (Token::Match(decltok->tokAt(-2), "%type% * %var%")) { sz = sizeOfType(decltok->tokAt(-2)); } + // Multi-dimensional array.. + if (Token::Match(decltok,"%var% [") && Token::simpleMatch(decltok->linkAt(1), "] [")) { + const Token *tok2 = decltok->linkAt(1); + while (Token::Match(tok2, "] [ %num% ]")) { + sz = sz * MathLib::toLongNumber(tok2->strAt(2)); + tok2 = tok2->linkAt(3); + } + if (Token::simpleMatch(tok2, "] [")) + sz = 0; + } } else if (tok->strAt(3) == "[" && tok->tokAt(2)->isStandardType()) { sz = sizeOfType(tok->tokAt(2)); if (sz == 0) diff --git a/test/testsimplifytokens.cpp b/test/testsimplifytokens.cpp index b3802b8da..65ff39f19 100644 --- a/test/testsimplifytokens.cpp +++ b/test/testsimplifytokens.cpp @@ -65,9 +65,7 @@ private: TEST_CASE(elseif1); TEST_CASE(ifa_ifa); // "if (a) { if (a) .." => "if (a) { if (1) .." - TEST_CASE(sizeof2); - TEST_CASE(sizeof3); - TEST_CASE(sizeof4); + TEST_CASE(sizeof_array); TEST_CASE(sizeof5); TEST_CASE(sizeof6); TEST_CASE(sizeof7); @@ -1028,38 +1026,37 @@ private: - void sizeof2() { - const char code[] = "void foo()\n" + void sizeof_array() { + const char *code; + + code = "void foo()\n" "{\n" " int i[4];\n" " sizeof(i);\n" " sizeof(*i);\n" "}\n"; ASSERT_EQUALS("void foo ( ) { int i [ 4 ] ; 16 ; 4 ; }", tok(code)); - } - void sizeof3() { - const char code[] = "static int i[4];\n" + code = "static int i[4];\n" "void f()\n" "{\n" " int i[10];\n" " sizeof(i);\n" "}\n"; ASSERT_EQUALS("static int i [ 4 ] ; void f ( ) { int i [ 10 ] ; 40 ; }", tok(code)); - } - - void sizeof4() { { - const char code[] = "int i[10];\n" + code = "int i[10];\n" "sizeof(i[0]);\n"; ASSERT_EQUALS("int i [ 10 ] ; 4 ;", tok(code)); - } - { - const char code[] = "int i[10];\n" + code = "int i[10];\n" "sizeof i[0];\n"; ASSERT_EQUALS("int i [ 10 ] ; 4 ;", tok(code)); } + + code = "char i[2][20];\n" + "sizeof(i[1]);"; + ASSERT_EQUALS("char i [ 2 ] [ 20 ] ; 20 ;", tok(code)); } void sizeof5() {