Skip to content

Two solution proposals for TRAC #7567 ("(a | 7) > 6U" is always true ...)#816

Closed
bartlomiejgrzeskowiak wants to merge 1 commit into
cppcheck-opensource:masterfrom
bartlomiejgrzeskowiak:master
Closed

Two solution proposals for TRAC #7567 ("(a | 7) > 6U" is always true ...)#816
bartlomiejgrzeskowiak wants to merge 1 commit into
cppcheck-opensource:masterfrom
bartlomiejgrzeskowiak:master

Conversation

@bartlomiejgrzeskowiak
Copy link
Copy Markdown
Contributor

@bartlomiejgrzeskowiak bartlomiejgrzeskowiak commented Jul 31, 2016

This is a solution proposal for TRAC #7567 and all "==|!=|>|>=|<|<=" comparisons. I will appreciate your opinions especially about:

  • considering "Four-eyes principle" please check the logic of proposed solution
  • please notify if you have any additional test cases
    My consideration is "Expression '(X & 0x0) == 0x0' is always true", and "Expression '(X | max(X)) == max(X)' is always true for unsigned X". Is there any way to check max(X) ?
  • I have proposed 2 solutions in 2 different commits. Please choose the one you prefer
    TRAC fixed #13906 - ErrorMessage::FileLocation did not simplify the file in all cases #7567: distinct implementation
    TRAC fixed #13906 - ErrorMessage::FileLocation did not simplify the file in all cases #7567: compact implementation
  • since I am still not sure if binary operations on signed variables are safe and justified could you please give some use examples in real code ? I use binary ops mostly for reading registers in embedded world, and even ">,>=,<,<=" comparisons are strange in this area.
  • my test cases were collected in a "cherry-picking" way. I guess there should be a way to do it in more systematic way by analysing a properties of binary operations. Do you have any ideas how to start with it ?
  • there are a few duplicated newlines in lib/checkcondition.cpp (l.42, l.201,l.396 ...). Should I remove them within the same PullRequest ?
  • I think the code would be more readable if the functions in test/testcondition.cpp would have names corresponding to the implementations in lib/checkcondition.cpp. In that case I would put all my testcases into new "void checkcomparison()" function in test/testcondition.cpp.

@danmar
Copy link
Copy Markdown
Collaborator

danmar commented Aug 1, 2016

I think the code would be more readable if the functions in test/testcondition.cpp would have names corresponding to the implementations in lib/checkcondition.cpp.

I agree. I would like if we always used the same name.

@danmar
Copy link
Copy Markdown
Collaborator

danmar commented Aug 1, 2016

I want to avoid copy paste. so basically the compact is better.

I would recommend that we reorder the code:

if (Token::Match(tok, "==|!=")) {
    ... keep the existing code ...
} else if (expr1->str() == "&") {
    // check < <= => > ...
} else if (expr1->str() == "|") {
    // check < <= => > ...
}

@danmar
Copy link
Copy Markdown
Collaborator

danmar commented Aug 1, 2016

there are a few duplicated newlines in lib/checkcondition.cpp (l.42, l.201,l.396 ...). Should I remove them within the same PullRequest ?

thanks. it would not be totally wrong. but I think I prefer that you don't do it here. those lines are not near your changes.

I like that you try to see if there is an opportunity to cleanup the code.

@danmar
Copy link
Copy Markdown
Collaborator

danmar commented Aug 1, 2016

since I am still not sure if binary operations on signed variables are safe and justified could you please give some use examples in real code ? I use binary ops mostly for reading registers in embedded world, and even ">,>=,<,<=" comparisons are strange in this area.

I agree it's strange with negative values. I would feel 99% confident about saying that (i|7>0) is always true even though i is signed. Off the top of my head I can't give a example in real code where negative values are used in bitoperations.

I also agree that ">,>=,<,<=" are strange.

@danmar
Copy link
Copy Markdown
Collaborator

danmar commented Aug 1, 2016

My consideration is "Expression '(X & 0x0) == 0x0' is always true", and "Expression '(X | max(X)) == max(X)' is always true for unsigned X". Is there any way to check max(X) ?

I hope we don't warn about '(X | max(X)) == max(X)'. Consider:

void f(unsigned int x) {
    if ((X | 0xFFFF) == 0xFFFF) {}
}

That is always true on a 16-bit platform. But I think we should assume the code is portable and might be executed on other platforms also.

Comment thread lib/checkcondition.cpp Outdated

for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "==|!=|>")) {
if (Token::Match(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.

could you please replace this with a:

if (!tok->isComparisonOp())
    continue;

@danmar
Copy link
Copy Markdown
Collaborator

danmar commented Aug 6, 2016

It looks pretty good now.

I am thinking about splitting the tests into three test functions. the checker checks "==|!=", "&" and "|" separately. so we could have separate test functions for those. what do you think?

Comment thread lib/checkcondition.cpp Outdated
} else if (expr1->str() == "&") {
const bool or_equal = Token::Match(tok, ">=|<=");
const std::string& op(tok->str());
if ((Token::Match(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 would write this condition on 1 line

@bartlomiejgrzeskowiak
Copy link
Copy Markdown
Contributor Author

I am not sure about splitting test functions. It will brake the concept of same names for checker/test function names. Secondly comparison function is for huge in my opinion.

But, you are the boss ;) I can split it by for example:
comparison_equal_not_equal()
comparison_or()
comparison_and()

@danmar
Copy link
Copy Markdown
Collaborator

danmar commented Aug 7, 2016

Thanks! I applied this with 09a83f2. I think splitting the testfunction is optional, it's not required.

@danmar danmar closed this Aug 7, 2016
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