Fixed #5860: Don't show returnTempReference for calculations on unknown types

This commit is contained in:
PKEuS 2014-05-24 12:32:44 +02:00
parent adf38fcfd0
commit a04036337d
3 changed files with 40 additions and 2 deletions

View File

@ -327,6 +327,34 @@ bool CheckAutoVariables::returnTemporary(const Token *tok) const
//---------------------------------------------------------------------------
static bool astHasAutoResult(const Token *tok)
{
if (tok->astOperand1() && !astHasAutoResult(tok->astOperand1()))
return false;
if (tok->astOperand2() && !astHasAutoResult(tok->astOperand2()))
return false;
if (tok->isOp())
return true;
if (tok->isLiteral())
return true;
if (tok->isName()) {
// TODO: check function calls, struct members, arrays, etc also
if (!tok->variable())
return false;
if (tok->variable()->isStlType() && !Token::Match(tok->astParent(), "<<|>>"))
return true;
if (tok->variable()->isClass() || tok->variable()->isPointer() || tok->variable()->isReference()) // TODO: Properly handle pointers/references to classes in symbol database
return false;
return true;
}
return false;
}
void CheckAutoVariables::returnReference()
{
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
@ -377,7 +405,7 @@ void CheckAutoVariables::returnReference()
}
// Return reference to a literal or the result of a calculation
else if (tok2->astOperand1() && (tok2->astOperand1()->isCalculation() || tok2->next()->isLiteral())) {
else if (tok2->astOperand1() && (tok2->astOperand1()->isCalculation() || tok2->next()->isLiteral()) && astHasAutoResult(tok2->astOperand1())) {
errorReturnTempReference(tok2);
}
}

View File

@ -254,7 +254,7 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
// Skip casts
if (tok->str() == "(") {
tok = tok->link();
if(tok)
if (tok)
tok = tok->next();
}

View File

@ -867,6 +867,16 @@ private:
"}");
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("Unknown1& operator<<(Unknown1 out, Unknown2 path) {\n"
" return out << path;\n"
"}");
ASSERT_EQUALS("", errout.str());
check("int& a(int b) {\n"
" return 2*(b+1);\n"
"}");