Fix #11371 Detect assignment to temporary (#4571)

* Fix #11371 Detect assignment to temporary

* Use AST

* Warn if type definition is not seen
This commit is contained in:
chrchr-github 2022-11-01 11:46:42 +01:00 committed by GitHub
parent cf8051b7e2
commit d717e62ec3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 4 deletions

View File

@ -2120,16 +2120,24 @@ void CheckOther::checkMisusedScopedObject()
misusedScopeObjectError(ctorTok, typeStr);
tok = tok->next();
}
if (tok->isAssignmentOp() && Token::simpleMatch(tok->astOperand1(), "(") && tok->astOperand1()->astOperand1()) {
if (const Function* ftok = tok->astOperand1()->astOperand1()->function()) {
if (ftok->retType && Token::Match(ftok->retType->classDef, "class|struct|union") && !Function::returnsReference(ftok))
misusedScopeObjectError(tok->next(), ftok->retType->name(), /*isAssignment*/ true);
}
}
}
}
}
void CheckOther::misusedScopeObjectError(const Token *tok, const std::string& varname)
void CheckOther::misusedScopeObjectError(const Token *tok, const std::string& varname, bool isAssignment)
{
std::string msg = "Instance of '$symbol' object is destroyed immediately";
msg += isAssignment ? ", assignment has no effect." : ".";
reportError(tok, Severity::style,
"unusedScopedObject",
"$symbol:" + varname + "\n"
"Instance of '$symbol' object is destroyed immediately.", CWE563, Certainty::normal);
"$symbol:" + varname + "\n" +
msg, CWE563, Certainty::normal);
}
static const Token * getSingleExpressionInBlock(const Token * tok)

View File

@ -251,7 +251,7 @@ private:
void redundantBitwiseOperationInSwitchError(const Token *tok, const std::string &varname);
void suspiciousCaseInSwitchError(const Token* tok, const std::string& operatorString);
void selfAssignmentError(const Token *tok, const std::string &varname);
void misusedScopeObjectError(const Token *tok, const std::string &varname);
void misusedScopeObjectError(const Token *tok, const std::string &varname, bool isAssignment = false);
void duplicateBranchError(const Token *tok1, const Token *tok2, ErrorPath errors);
void duplicateAssignExpressionError(const Token *tok1, const Token *tok2, bool inconclusive);
void oppositeExpressionError(const Token *opTok, ErrorPath errors);

View File

@ -140,6 +140,7 @@ private:
TEST_CASE(testMisusedScopeObjectInConstructor);
TEST_CASE(testMisusedScopeObjectStandardType);
TEST_CASE(testMisusedScopeObjectNamespace);
TEST_CASE(testMisusedScopeObjectAssignment); // #11371
TEST_CASE(trac2071);
TEST_CASE(trac2084);
TEST_CASE(trac3693);
@ -5136,6 +5137,19 @@ private:
errout.str());
}
void testMisusedScopeObjectAssignment() { // #11371
check("struct S;\n"
"S f();\n"
"S& g();\n"
"S&& h();\n"
"S* i();\n"
"void t0() { f() = {}; }\n"
"void t1() { g() = {}; }\n"
"void t2() { h() = {}; }\n"
"void t3() { *i() = {}; }\n", "test.cpp");
ASSERT_EQUALS("[test.cpp:6]: (style) Instance of 'S' object is destroyed immediately, assignment has no effect.\n", errout.str());
}
void trac2084() {
check("void f()\n"
"{\n"