Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2617,6 +2617,14 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti
return false;
}

static bool hasOverloadedMemberAccess(const Token* tok)
{
if (!Token::simpleMatch(tok, "."))
return false;
const Token* varTok = tok->astOperand2();
return !varTok || !varTok->variable() || !varTok->variable()->valueType() || varTok->variable()->valueType()->pointer == 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will return true for smart pointers. This should probably be named isOwnerWithDeref or something like that. We should also add optional to the library config, but we could check for class names optional.


bool isVariableChanged(const Token *tok, int indirect, const Settings &settings, int depth)
{
if (!isMutableExpression(tok))
Expand All @@ -2631,7 +2639,7 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings &settings,
(Token::simpleMatch(tok2->astParent(), ".") && !Token::Match(tok2->astParent()->astParent(), "[(,]")) ||
(tok2->astParent() && tok2->astParent()->isUnaryOp("&") && Token::simpleMatch(tok2->astParent()->astParent(), ".") && tok2->astParent()->astParent()->originalName()=="->") ||
(Token::simpleMatch(tok2->astParent(), "[") && tok2 == tok2->astParent()->astOperand1())) {
if (tok2->astParent() && (tok2->astParent()->isUnaryOp("*") || (astIsLHS(tok2) && tok2->astParent()->originalName() == "->")))
if (tok2->astParent() && (tok2->astParent()->isUnaryOp("*") || (astIsLHS(tok2) && tok2->astParent()->originalName() == "->" && !hasOverloadedMemberAccess(tok2))))
derefs++;
if (derefs > indirect)
break;
Expand Down
7 changes: 7 additions & 0 deletions test/testother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3974,6 +3974,13 @@ class TestOther : public TestFixture {
" return (void*)&s;\n"
"}\n"); // don't crash
ASSERT_EQUALS("", errout_str());

check("struct S { int i; };\n" // #14251
"struct T { std::optional<S> s; };\n"
"void f(T& t) {\n"
" t.s->i = 0;\n"
"}\n");
ASSERT_EQUALS("", errout_str());
}

void constParameterCallback() {
Expand Down