From 63d96e49fc57b63aeb3fb25bf843aec67ef8e2bc Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Sun, 27 Mar 2022 07:59:29 +0200 Subject: [PATCH] Fix #10928, #10930 FP constStatement (#3946) * Fix #10928, #10930 FP constStatement * Fix test cases (first one did not compile) --- lib/astutils.cpp | 4 ++-- lib/astutils.h | 2 +- lib/checkother.cpp | 4 +++- test/testincompletestatement.cpp | 10 +++++++++- test/testother.cpp | 2 +- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 141eb9cef..70a7ccc0a 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1748,7 +1748,7 @@ bool isConstExpression(const Token *tok, const Library& library, bool pure, bool return isConstExpression(tok->astOperand1(), library, pure, cpp) && isConstExpression(tok->astOperand2(), library, pure, cpp); } -bool isWithoutSideEffects(bool cpp, const Token* tok, bool checkArrayAccess) +bool isWithoutSideEffects(bool cpp, const Token* tok, bool checkArrayAccess, bool checkReference) { if (!cpp) return true; @@ -1757,7 +1757,7 @@ bool isWithoutSideEffects(bool cpp, const Token* tok, bool checkArrayAccess) tok = tok->astOperand2(); if (tok && tok->varId()) { const Variable* var = tok->variable(); - return var && (!var->isClass() || var->isPointer() || (checkArrayAccess ? var->isStlType() && !var->isStlType(CheckClass::stl_containers_not_const) : var->isStlType())); + return var && ((!var->isClass() && (checkReference || !var->isReference())) || var->isPointer() || (checkArrayAccess ? var->isStlType() && !var->isStlType(CheckClass::stl_containers_not_const) : var->isStlType())); } return true; } diff --git a/lib/astutils.h b/lib/astutils.h index c29e59ee3..0fb4e39e0 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -227,7 +227,7 @@ bool isConstFunctionCall(const Token* ftok, const Library& library); bool isConstExpression(const Token *tok, const Library& library, bool pure, bool cpp); -bool isWithoutSideEffects(bool cpp, const Token* tok, bool checkArrayAccess = false); +bool isWithoutSideEffects(bool cpp, const Token* tok, bool checkArrayAccess = false, bool checkReference = true); bool isUniqueExpression(const Token* tok); diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 325ee63c2..036e817c9 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1771,6 +1771,8 @@ static bool isConstStatement(const Token *tok, bool cpp) return false; if (tok->astTop() && Token::simpleMatch(tok->astTop()->astOperand1(), "delete")) return false; + if (Token::Match(tok, "&&|%oror%")) + return isConstStatement(tok->astOperand1(), cpp) && isConstStatement(tok->astOperand2(), cpp); if (Token::Match(tok, "!|~|%cop%") && (tok->astOperand1() || tok->astOperand2())) return true; if (Token::simpleMatch(tok->previous(), "sizeof (")) @@ -1785,7 +1787,7 @@ static bool isConstStatement(const Token *tok, bool cpp) return tok->astParent() ? isConstStatement(tok->astOperand1(), cpp) && isConstStatement(tok->astOperand2(), cpp) : isConstStatement(tok->astOperand2(), cpp); if (Token::simpleMatch(tok, "?") && Token::simpleMatch(tok->astOperand2(), ":")) // ternary operator return isConstStatement(tok->astOperand1(), cpp) && isConstStatement(tok->astOperand2()->astOperand1(), cpp) && isConstStatement(tok->astOperand2()->astOperand2(), cpp); - if (isBracketAccess(tok) && isWithoutSideEffects(cpp, tok->astOperand1(), /*checkArrayAccess*/ true)) { + if (isBracketAccess(tok) && isWithoutSideEffects(cpp, tok->astOperand1(), /*checkArrayAccess*/ true, /*checkReference*/ false)) { if (Token::simpleMatch(tok->astParent(), "[")) return isConstStatement(tok->astOperand2(), cpp) && isConstStatement(tok->astParent(), cpp); return isConstStatement(tok->astOperand2(), cpp); diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index e251b7c5f..0c249ac9e 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -517,7 +517,7 @@ private: "[test.cpp:12]: (warning) Redundant code: Found unused array access.\n", errout.str()); - check("void g() {\n" + check("void g(std::map& map) {\n" " int j[2]{};\n" " int k[2] = {};\n" " int l[]{ 1, 2 };\n" @@ -531,6 +531,7 @@ private: " j[0][0][h()];\n" " std::map M;\n" " M[\"abc\"];\n" + " map[\"abc\"];\n" // #10928 " std::auto_ptr app[4];" // #10919 "}\n"); ASSERT_EQUALS("", errout.str()); @@ -608,6 +609,13 @@ private: " params_given (params, \"overrides\") || (overrides = \"1\");\n" "}", true); ASSERT_EQUALS("", errout.str()); + + check("void f(std::ifstream& file) {\n" // #10930 + " int a{}, b{};\n" + " (file >> a) || (file >> b);\n" + " (file >> a) && (file >> b);\n" + "}\n", true); + ASSERT_EQUALS("", errout.str()); } }; diff --git a/test/testother.cpp b/test/testother.cpp index dd92048eb..5ce81fa12 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4396,7 +4396,7 @@ private: " {\n" " x = y = z = 0.0;\n" " }\n" - " V( double x, const double y, const double &z )\n" + " V( double x, const double y_, const double &z_)\n" " {\n" " x = x; y = y; z = z;\n" " }\n"