Skip to content

Fix CheckClass::operatorEqToSelf#3088

Merged
danmar merged 5 commits into
cppcheck-opensource:mainfrom
alonlib12:Fix-operatorEqToSelf
Feb 2, 2021
Merged

Fix CheckClass::operatorEqToSelf#3088
danmar merged 5 commits into
cppcheck-opensource:mainfrom
alonlib12:Fix-operatorEqToSelf

Conversation

@alonlib12
Copy link
Copy Markdown
Contributor

No description provided.

@alonlib12
Copy link
Copy Markdown
Contributor Author

Fix CheckClass::operatorEqToSelf false negative cases.

Comment thread lib/checkclass.cpp Outdated
return res;
}

const Token * CheckClass::getScopeStartToken(const Token *tok)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

hmm .. this is a strange name. With this name I would have thought it worked like tok->scope()->bodyStart.

I guess I'd prefer that you use tok->astTop() instead of a for loop. I assume that we only are interested in the top.

Then instead of such condition: itr->link()->next() && itr->link()->next()->str() == "{" I'd prefer Token::simpleMatch(itr->link(), ") {"). That is more explicit and also avoid extra calls for link() and next().

Copy link
Copy Markdown
Collaborator

@danmar danmar Jan 29, 2021

Choose a reason for hiding this comment

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

I think the name is strange but do not have a suggestion right now.. feel free to suggest a name that is more specific.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment thread lib/checkclass.cpp Outdated
if (itr->str() == "!=" && (itr->astOperand1()->str() == "true" || itr->astOperand2()->str() == "true")) {
res = !res;
}
else if (itr->str() == "!=" && (itr->astOperand1()->str() != "false" && itr->astOperand2()->str() != "false")) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

In general I prefer that we use valueflow instead of hardcoded constants. A false token has the known integer value 0..

 (... astOperand1()->hasKnownIntValue() && .. astOperand1()->getKnownIntValue() != 0 )

.. and a true token has the value 1 ..

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment thread lib/checkclass.cpp Outdated
}

bool CheckClass::hasAssignSelf(const Function *func, const Token *rhs)
bool CheckClass::isInverseAssignmentTest(const Token *tok)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

hmm.. spontaneously I have the feeling this has some overlap for what we want to achieve with astIsVariableComparison. maybe I am wrong.

Copy link
Copy Markdown
Contributor Author

@alonlib12 alonlib12 Jan 30, 2021

Choose a reason for hiding this comment

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

isInverseAssignmentTest checks if a self-assignment test is inverse.
For example, for if (this == &rhs) and if (!(this != &rhs)) the function will return true, and for
if (this != &rhs) it will return false.
Can I achieve this with astIsVariableComparison?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

hmm.. you can implement this for now.

And then I can try to see if some refactoring / improvements can be made later.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think a name that explains what the function do is better than a name that explains when it is used. The "Assignment" has nothing to do with the functionality of the function.

Something like isInverted or something like that will work for me..

Maybe we should also consider that in practice the result is not false/true but false/maybe/true.

if (foo && this == &rhs)

The address of rhs may or may not be this when this condition is true/false.

If the result is "maybe" it's better to bailout and don't write warnings if that can avoid false positives.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

@danmar
Copy link
Copy Markdown
Collaborator

danmar commented Jan 29, 2021

sorry I forgot this PR. If you don't get a review in 1-2 days.. feel free to ping me. you can write @danmar in a comment.

Copy link
Copy Markdown
Collaborator

@danmar danmar left a comment

Choose a reason for hiding this comment

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

Thanks for working on this! I think it looks promising, but I have more nits.

Comment thread lib/checkclass.cpp Outdated
return false;
}

bool CheckClass::isTrueKeyword(const Token* tok)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd prefer that this was a local function. Not part of CheckClass. No need to declare it in the header.

Comment thread lib/checkclass.cpp Outdated
}

const Token * CheckClass::getScopeStartToken(const Token *tok)
const Token * CheckClass::getIfStmtScopeStart(const Token *tok)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this name is better. but I'd suggest getIfStmtBodyStart.

Comment thread lib/checkclass.cpp Outdated
}

bool CheckClass::hasAssignSelf(const Function *func, const Token *rhs)
bool CheckClass::isInverseAssignmentTest(const Token *tok)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

hmm.. you can implement this for now.

And then I can try to see if some refactoring / improvements can be made later.

Comment thread lib/checkclass.cpp Outdated
Comment thread lib/checkclass.cpp Outdated
}

bool CheckClass::hasAssignSelf(const Function *func, const Token *rhs)
bool CheckClass::isInverseAssignmentTest(const Token *tok)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think a name that explains what the function do is better than a name that explains when it is used. The "Assignment" has nothing to do with the functionality of the function.

Something like isInverted or something like that will work for me..

Maybe we should also consider that in practice the result is not false/true but false/maybe/true.

if (foo && this == &rhs)

The address of rhs may or may not be this when this condition is true/false.

If the result is "maybe" it's better to bailout and don't write warnings if that can avoid false positives.

@alonlib12
Copy link
Copy Markdown
Contributor Author

@danmar ping

@danmar danmar merged commit a22e476 into cppcheck-opensource:main Feb 2, 2021
@danmar
Copy link
Copy Markdown
Collaborator

danmar commented Feb 2, 2021

I would like to add your name in our AUTHORS. What name would you like that I add?

@alonlib12
Copy link
Copy Markdown
Contributor Author

alonlib12 commented Feb 2, 2021 via email

uhziel pushed a commit to uhziel/cppcheck that referenced this pull request Feb 25, 2021
…r union member is never used" for structs with __attribute__((packed)) or #pragma pack(push))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants