Improved check: Complain about returning reference to literals or reference to calculation result (#4317)
This commit is contained in:
parent
35f644542e
commit
6635abbe55
|
@ -344,6 +344,9 @@ void CheckAutoVariables::returnReference()
|
|||
// have we reached a function that returns a reference?
|
||||
if (tok->previous() && tok->previous()->str() == "&") {
|
||||
for (const Token *tok2 = scope->classStart->next(); tok2 && tok2 != scope->classEnd; tok2 = tok2->next()) {
|
||||
if (tok2->str() != "return")
|
||||
continue;
|
||||
|
||||
// return..
|
||||
if (Token::Match(tok2, "return %var% ;")) {
|
||||
// is the returned variable a local variable?
|
||||
|
@ -374,6 +377,11 @@ void CheckAutoVariables::returnReference()
|
|||
errorReturnTempReference(tok2);
|
||||
}
|
||||
}
|
||||
|
||||
// Return reference to a literal or the result of a calculation
|
||||
else if (tok2->astOperand1() && (tok2->astOperand1()->isCalculation() || tok2->next()->isLiteral())) {
|
||||
errorReturnTempReference(tok2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,8 @@ private:
|
|||
TEST_CASE(returnReference5);
|
||||
TEST_CASE(returnReference6);
|
||||
TEST_CASE(returnReference7);
|
||||
TEST_CASE(returnReferenceLiteral);
|
||||
TEST_CASE(returnReferenceCalculation);
|
||||
|
||||
// global namespace
|
||||
TEST_CASE(testglobalnamespace);
|
||||
|
@ -847,6 +849,45 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void returnReferenceLiteral() {
|
||||
check("const std::string &a() {\n"
|
||||
" return \"foo\";\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Reference to temporary returned.\n", errout.str());
|
||||
|
||||
check("const std::string a() {\n"
|
||||
" return \"foo\";\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void returnReferenceCalculation() {
|
||||
check("const std::string &a(const std::string& str) {\n"
|
||||
" return \"foo\" + str;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Reference to temporary returned.\n", errout.str());
|
||||
|
||||
check("int& a(int b) {\n"
|
||||
" return 2*(b+1);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Reference to temporary returned.\n", errout.str());
|
||||
|
||||
check("const std::string &a(const std::string& str) {\n"
|
||||
" return str;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("const std::string &a(int bar) {\n"
|
||||
" return foo(bar + 1);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("const std::string a(const std::string& str) {\n"
|
||||
" return \"foo\" + str;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
|
||||
void testglobalnamespace() {
|
||||
check("class SharedPtrHolder\n"
|
||||
|
|
Loading…
Reference in New Issue