diff --git a/lib/checkautovariables.cpp b/lib/checkautovariables.cpp index 6d433df81..9c38401e8 100644 --- a/lib/checkautovariables.cpp +++ b/lib/checkautovariables.cpp @@ -349,8 +349,15 @@ static bool astHasAutoResult(const Token *tok) if (tok->astOperand2() && !astHasAutoResult(tok->astOperand2())) return false; - if (tok->isOp()) + if (tok->isOp()) { + if ((tok->str() == "<<" || tok->str() == ">>") && tok->astOperand1()) { + const Token* tok2 = tok->astOperand1(); + while (tok2 && tok2->str() == "*" && !tok2->astOperand2()) + tok2 = tok2->astOperand1(); + return tok2 && tok2->variable() && !tok2->variable()->isClass() && !tok2->variable()->isStlType(); // Class or unknown type on LHS: Assume it is a stream + } return true; + } if (tok->isLiteral()) return true; @@ -359,7 +366,7 @@ static bool astHasAutoResult(const Token *tok) // TODO: check function calls, struct members, arrays, etc also if (!tok->variable()) return false; - if (tok->variable()->isStlType() && !Token::Match(tok->astParent(), "<<|>>")) + if (tok->variable()->isStlType()) return true; if (tok->variable()->isClass() || tok->variable()->isPointer() || tok->variable()->isReference()) // TODO: Properly handle pointers/references to classes in symbol database return false; diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 77fe3a664..9dc7d9acf 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -882,11 +882,21 @@ private: "}"); ASSERT_EQUALS("[test.cpp:2]: (error) Reference to temporary returned.\n", errout.str()); + check("int& operator<<(int out, int path) {\n" + " return out << path;\n" + "}"); + ASSERT_EQUALS("[test.cpp:2]: (error) Reference to temporary returned.\n", errout.str()); + check("std::ostream& operator<<(std::ostream& out, const std::string& path) {\n" " return out << path;\n" "}"); ASSERT_EQUALS("", errout.str()); + check("std::ostream& operator<<(std::ostream* out, const std::string& path) {\n" + " return *out << path;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + check("Unknown1& operator<<(Unknown1 out, Unknown2 path) {\n" " return out << path;\n" "}");