Skip to content

C++: IR translation for binary conditional operator #3307

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 22, 2020
Merged

C++: IR translation for binary conditional operator #3307

merged 4 commits into from
Apr 22, 2020

Conversation

dbartol
Copy link

@dbartol dbartol commented Apr 21, 2020

IR generation was not handling the special two-operand flavor of the ?: operator that GCC supports as an extension. The extractor doesn't quite give us enough information to do this correctly (see github/codeql-c-extractor-team#67), but we can get pretty close.

About half of the code could be shared between the two-operand and three-operand flavors. The main differences for the two-operand flavor are:

  1. The "then" operand isn't a child of the ConditionalExpr. Instead, we just reuse the original value of the "condition" operand, skipping any implicit cast to bool (see comment for rationale).
  2. For the three-operand flavor, we generate the condition as control flow rather than the computation of a bool value, to avoid creating unnecessarily complicated branching. For the two-operand version, we just compute the value, since we have to reuse that value in the "then" branch anyway.

I've added IR tests for these new cases. I've also updated the expectations for SignAnalysis.ql based on the fix. @rdmarsh2, can you please double-check that these diffs look correct? I believe they do, but you're the range/sign analysis expert.

IR generation was not handling the special two-operand flavor of the `?:` operator that GCC supports as an extension. The extractor doesn't quite give us enough information to do this correctly (see github/codeql-c-extractor-team#67), but we can get pretty close.

About half of the code could be shared between the two-operand and three-operand flavors. The main differences for the two-operand flavor are:
1. The "then" operand isn't a child of the `ConditionalExpr`. Instead, we just reuse the original value of the "condition" operand, skipping any implicit cast to `bool` (see comment for rationale).
2. For the three-operand flavor, we generate the condition as control flow rather than the computation of a `bool` value, to avoid creating unnecessarily complicated branching. For the two-operand version, we just compute the value, since we have to reuse that value in the "then" branch anyway.

I've added IR tests for these new cases. I've also updated the expectations for `SignAnalysis.ql` based on the fix. @rdmarsh2, can you please double-check that these diffs look correct? I believe they do, but you're the range/sign analysis expert.
@dbartol dbartol added the C++ label Apr 21, 2020
@dbartol dbartol requested a review from jbj April 21, 2020 06:06
@dbartol dbartol requested a review from a team as a code owner April 21, 2020 06:06
@rdmarsh2
Copy link
Contributor

The sign analysis results are either improvements or cases where it was previously right for the wrong reasons. We don't run the range analysis on the same set of tests, so I'm not sure if there's regressions there. I'll check that and then do a proper code review.

Comment on lines +1906 to +1908
// A `ThrowExpr.getType()` incorrectly returns the type of exception being
// thrown, rather than `void`. Handle that case here.
expr.getThen() instanceof ThrowExpr
Copy link
Contributor

Choose a reason for hiding this comment

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

File an extractor bug?

Copy link
Author

Choose a reason for hiding this comment

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

https://github.com/github/codeql-c-extractor-team/issues/67 (already linked in the commit message)

Copy link
Contributor

Choose a reason for hiding this comment

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

I meant for ThrowExpr.getType(), unless that's something we think users rely on.

@rdmarsh2 rdmarsh2 merged commit 471f536 into github:master Apr 22, 2020
@dbartol dbartol deleted the dbartol/BinaryConditional branch April 24, 2020 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants