Better support for stream operator in CheckAutoVariables::returnReference() (#6423)
This commit is contained in:
parent
9deffc088d
commit
36841cfa41
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
"}");
|
"}");
|
||||||
|
|
Loading…
Reference in New Issue