From 103e52f394fe504ce3fbbd1f371e1678c5628609 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Thu, 11 Mar 2021 08:16:25 +0100 Subject: [PATCH] Fix tokenizing of x[i](0) (Fixes #8875) (#3167) Fix faulty removal of parenthesis when "]" is followed by parenthesis with a number inside, for example when calling a function pointer in an array or (perhaps more common) in c++, calling operator ( on an element in an array. Fixes #8875 where such wrong simplification lead to a FP with too many bits shifted due to "<<" was interpreted like a shift operator rather than a stream output. --- lib/tokenize.cpp | 4 ++-- test/testtokenize.cpp | 7 +++++++ test/testtype.cpp | 6 ++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index a6fa112fd..37b192c74 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8741,11 +8741,11 @@ bool Tokenizer::simplifyRedundantParentheses() ret = true; } - // Simplify "!!operator !!%name%|)|>|>> ( %num%|%bool% ) %op%|;|,|)" + // Simplify "!!operator !!%name%|)|]|>|>> ( %num%|%bool% ) %op%|;|,|)" if (Token::Match(tok, "( %bool%|%num% ) %cop%|;|,|)") && tok->strAt(-2) != "operator" && tok->previous() && - !Token::Match(tok->previous(), "%name%|)") && + !Token::Match(tok->previous(), "%name%|)|]") && (!(isCPP() && Token::Match(tok->previous(),">|>>")))) { tok->link()->deleteThis(); tok->deleteThis(); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 0aae262f6..635f7613a 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -171,6 +171,7 @@ private: TEST_CASE(removeParentheses23); // Ticket #6103 - Infinite loop upon valid input TEST_CASE(removeParentheses24); // Ticket #7040 TEST_CASE(removeParentheses25); // daca@home - a=(b,c) + TEST_CASE(removeParentheses26); // Ticket #8875 a[0](0) TEST_CASE(tokenize_double); TEST_CASE(tokenize_strings); @@ -1676,6 +1677,12 @@ private: ASSERT_EQUALS(exp, tokenizeAndStringify(code)); } + void removeParentheses26() { // Ticket #8875 a[0](0) + static char code[] = "a[0](0);"; + static char exp[] = "a [ 0 ] ( 0 ) ;"; + ASSERT_EQUALS(exp, tokenizeAndStringify(code)); + } + void tokenize_double() { const char code[] = "void f() {\n" " double a = 4.2;\n" diff --git a/test/testtype.cpp b/test/testtype.cpp index 06c25a008..7847f0e2b 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -204,6 +204,12 @@ private: " return -(y << (x-1));\n" "}"); ASSERT_EQUALS("", errout.str()); + + check("bool f() {\n" + " std::ofstream outfile;\n" + " outfile << vec_points[0](0) << static_cast(d) << ' ';\n" + "}"); + ASSERT_EQUALS("", errout.str()); } void checkIntegerOverflow() {