From c85e7e7d2f83a608b5c00163cd8971918cd6305e Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 30 Mar 2022 22:00:57 +0200 Subject: [PATCH] Fix FP constStatement with more complex expression (#3959) --- lib/checkother.cpp | 7 +++++-- test/testincompletestatement.cpp | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 7434189d4..c49a1f6d8 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1778,7 +1778,7 @@ static bool isConstStatement(const Token *tok, bool cpp) if (Token::simpleMatch(tok->previous(), "sizeof (")) return true; if (isCPPCast(tok)) { - if (Token::simpleMatch(tok->astOperand1(), "dynamic_cast") && Token::simpleMatch(tok->astOperand1()->next()->link()->previous(), "& >")) + if (Token::simpleMatch(tok->astOperand1(), "dynamic_cast") && Token::simpleMatch(tok->astOperand1()->linkAt(1)->previous(), "& >")) return false; return isWithoutSideEffects(cpp, tok) && isConstStatement(tok->astOperand2(), cpp); } @@ -1793,7 +1793,10 @@ static bool isConstStatement(const Token *tok, bool cpp) const Token* lml = previousBeforeAstLeftmostLeaf(tok); if (lml) lml = lml->next(); - return lml && !isLikelyStream(cpp, lml) && isConstStatement(tok->astOperand2(), cpp); + const Token* stream = lml; + while (stream && Token::Match(stream->astParent(), ".|[|(")) + stream = stream->astParent(); + return (!stream || !isLikelyStream(cpp, stream)) && isConstStatement(tok->astOperand2(), cpp); } } if (Token::simpleMatch(tok, "?") && Token::simpleMatch(tok->astOperand2(), ":")) // ternary operator diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index 829d0368f..b4462b2b6 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -377,6 +377,25 @@ private: " V << a, b, c, d;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + check("struct S { Eigen::Vector4d V; };\n" + "struct T { int a, int b, int c, int d; };\n" + "void f(S& s, const T& t) {\n" + " s.V << t.a, t.b, t.c, t.d;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("struct S { Eigen::Vector4d V[2]; };\n" + "void f(int a, int b, int c, int d) {\n" + " S s[1];\n" + " s[0].V[1] << a, b, c, d;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f() {\n" + " a.b[4][3].c()->d << x , y, z;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } // #8451