Better support for stream operator in CheckAutoVariables::returnReference() (#6423)

This commit is contained in:
PKEuS 2015-01-31 10:12:20 +01:00
parent 9deffc088d
commit 36841cfa41
2 changed files with 19 additions and 2 deletions

View File

@ -349,8 +349,15 @@ static bool astHasAutoResult(const Token *tok)
if (tok->astOperand2() && !astHasAutoResult(tok->astOperand2())) if (tok->astOperand2() && !astHasAutoResult(tok->astOperand2()))
return false; 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; return true;
}
if (tok->isLiteral()) if (tok->isLiteral())
return true; return true;
@ -359,7 +366,7 @@ static bool astHasAutoResult(const Token *tok)
// TODO: check function calls, struct members, arrays, etc also // TODO: check function calls, struct members, arrays, etc also
if (!tok->variable()) if (!tok->variable())
return false; return false;
if (tok->variable()->isStlType() && !Token::Match(tok->astParent(), "<<|>>")) if (tok->variable()->isStlType())
return true; return true;
if (tok->variable()->isClass() || tok->variable()->isPointer() || tok->variable()->isReference()) // TODO: Properly handle pointers/references to classes in symbol database if (tok->variable()->isClass() || tok->variable()->isPointer() || tok->variable()->isReference()) // TODO: Properly handle pointers/references to classes in symbol database
return false; return false;

View File

@ -882,11 +882,21 @@ private:
"}"); "}");
ASSERT_EQUALS("[test.cpp:2]: (error) Reference to temporary returned.\n", errout.str()); 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" check("std::ostream& operator<<(std::ostream& out, const std::string& path) {\n"
" return out << path;\n" " return out << path;\n"
"}"); "}");
ASSERT_EQUALS("", errout.str()); 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" check("Unknown1& operator<<(Unknown1 out, Unknown2 path) {\n"
" return out << path;\n" " return out << path;\n"
"}"); "}");