Fix #11383 FP selfAssignment: lambda capture / #11380 FP operatorEqRetRefThis (#4581)

* Fix  #11383 FP selfAssignment: lambda capture /  #11380
FP operatorEqRetRefThis

* Format
This commit is contained in:
chrchr-github 2022-11-13 21:20:44 +01:00 committed by GitHub
parent 8aec886450
commit 701d381895
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 10 deletions

View File

@ -1559,6 +1559,10 @@ void CheckClass::checkReturnPtrThis(const Scope *scope, const Function *func, co
for (; tok && tok != last; tok = tok->next()) { for (; tok && tok != last; tok = tok->next()) {
// check for return of reference to this // check for return of reference to this
if (const Token* lScope = isLambdaCaptureList(tok)) // skip lambda
tok = lScope->link();
if (tok->str() != "return") if (tok->str() != "return")
continue; continue;

View File

@ -2446,7 +2446,7 @@ void CheckOther::checkDuplicateExpression()
} }
} }
ErrorPath errorPath; ErrorPath errorPath;
if (tok->isOp() && tok->astOperand1() && !Token::Match(tok, "+|*|<<|>>|+=|*=|<<=|>>=")) { if (tok->isOp() && tok->astOperand1() && !Token::Match(tok, "+|*|<<|>>|+=|*=|<<=|>>=") && !isLambdaCaptureList(tok->astParent())) {
if (Token::Match(tok, "==|!=|-") && astIsFloat(tok->astOperand1(), true)) if (Token::Match(tok, "==|!=|-") && astIsFloat(tok->astOperand1(), true))
continue; continue;
const bool pointerDereference = (tok->astOperand1() && tok->astOperand1()->isUnaryOp("*")) || const bool pointerDereference = (tok->astOperand1() && tok->astOperand1()->isUnaryOp("*")) ||

View File

@ -1385,25 +1385,25 @@ static void compileExpression(Token *&tok, AST_state& state)
compileComma(tok, state); compileComma(tok, state);
} }
static bool isLambdaCaptureList(const Token * tok) const Token* isLambdaCaptureList(const Token * tok)
{ {
// a lambda expression '[x](y){}' is compiled as: // a lambda expression '[x](y){}' is compiled as:
// [ // [
// `-( <<-- optional // `-( <<-- optional
// `-{ // `-{
// see compilePrecedence2 // see compilePrecedence2
if (tok->str() != "[") if (!Token::simpleMatch(tok, "["))
return false; return nullptr;
if (!Token::Match(tok->link(), "] (|{")) if (!Token::Match(tok->link(), "] (|{"))
return false; return nullptr;
if (Token::simpleMatch(tok->astOperand1(), "{") && tok->astOperand1() == tok->link()->next()) if (Token::simpleMatch(tok->astOperand1(), "{") && tok->astOperand1() == tok->link()->next())
return true; return tok->astOperand1();
if (!tok->astOperand1() || tok->astOperand1()->str() != "(") if (!tok->astOperand1() || tok->astOperand1()->str() != "(")
return false; return nullptr;
const Token * params = tok->astOperand1(); const Token * params = tok->astOperand1();
if (!params->astOperand1() || params->astOperand1()->str() != "{") if (!Token::simpleMatch(params->astOperand1(), "{"))
return false; return nullptr;
return true; return params->astOperand1();
} }
// Compile inner expressions inside inner ({..}) and lambda bodies // Compile inner expressions inside inner ({..}) and lambda bodies

View File

@ -221,5 +221,7 @@ private:
/// @} /// @}
const Token* isLambdaCaptureList(const Token* tok);
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#endif // tokenlistH #endif // tokenlistH

View File

@ -1321,6 +1321,16 @@ private:
"};\n" "};\n"
"A::B & A::B::operator=(const A::B & b) { return b; }"); "A::B & A::B::operator=(const A::B & b) { return b; }");
ASSERT_EQUALS("[test.cpp:8]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str()); ASSERT_EQUALS("[test.cpp:8]: (style) 'operator=' should return reference to 'this' instance.\n", errout.str());
checkOpertorEqRetRefThis( // #11380
"struct S {\n"
" S& operator=(const S& other) {\n"
" i = []() { return 42; }();\n"
" return *this;\n"
" }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
} }
void operatorEqRetRefThis2() { void operatorEqRetRefThis2() {

View File

@ -4850,6 +4850,14 @@ private:
" }\n" " }\n"
"};\n"); "};\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("struct S {\n" // #11383
" void f() {\n"
" auto l2 = [i = i]() { return i; };\n"
" }\n"
" int i;\n"
"};\n");
ASSERT_EQUALS("", errout.str());
} }
void trac1132() { void trac1132() {