Skip to content

C++: Generate IR for __try __finally and __try __except #11761

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 10 commits into from
Dec 22, 2022

Conversation

MathiasVP
Copy link
Contributor

@MathiasVP MathiasVP commented Dec 20, 2022

This PR pickybags on our support for regular try statements to implement IR generation for __try __except (and __try __finally).

The QL changes are pretty simple, but due to the change in .expected files it's good to review this PR commit-by-commit.

@MathiasVP MathiasVP requested a review from a team as a code owner December 20, 2022 13:31
@github-actions github-actions bot added the C++ label Dec 20, 2022
@MathiasVP MathiasVP added the no-change-note-required This PR does not need a change note label Dec 20, 2022
@MathiasVP
Copy link
Contributor Author

DCA looks fine.

# 6| v6_6(void) = ExitFunction :

# 13| Block 1
# 13| r13_1(int) = Constant[0] :
Copy link
Contributor

Choose a reason for hiding this comment

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

What do we do in the case of a normal C++ catch? Is that just as messy as this right now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hopefully this will be fixed automagically once I fix the catch handling you helped me realize was bugged in your other comment.

Copy link
Contributor Author

@MathiasVP MathiasVP Dec 21, 2022

Choose a reason for hiding this comment

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

This is (partly) fixed in ff6e8a2. Just like for normal C++ exceptions, the catch block isn't actually reached by any gotos (this is something we really should fix in the IR eventually).

This Constant[0] was generated by the exception conditional in __except(0) { ... }, but it didn't continue to the exception block (which was definitely a bug). In ff6e8a2 we now correctly model the behavior specified by https://learn.microsoft.com/en-us/cpp/cpp/try-except-statement?view=msvc-170.

@MathiasVP
Copy link
Contributor Author

Thanks for the comments @jketema. It highlighted some bugs which should now be fixed. I'll start a new DCA run since quite a lot has changed since the first run.

Copy link

@github-advanced-security github-advanced-security bot left a comment

Choose a reason for hiding this comment

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

CodeQL found more than 10 potential problems in the proposed changes. Check the Files changed tab for more details.

@MathiasVP MathiasVP force-pushed the ir-for-microsoft-try-except-finally branch from 94ff797 to bbf0ec8 Compare December 21, 2022 14:41
@MathiasVP
Copy link
Contributor Author

Thanks for the comments @jketema. It highlighted some bugs which should now be fixed. I'll start a new DCA run since quite a lot has changed since the first run.

DCA still looks good :phew:

# 23| r23_2(int) = Constant[0] :
# 23| v23_3(void) = Call[ProbeFunction] : func:r23_1, 0:r23_2
# 23| mu23_4(unknown) = ^CallSideEffect : ~m?
# 26| r26_1(glval<unknown>) = FunctionAddress[sink] :
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess technically a new block should start here, or we need a special instruction here, as this point is directly reachable from all the statements in the __try block. Again this is probably now very relevant for dataflow at this point, so I propose to file an issue for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I completely agree. There's probably a large room for design here. I'll create an issue for it.

__finally {
sink(x);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at syntax zoo, could we also add something like the following here:

void h(int b) {
    __try {
        if (b) {
            throw 1;
        }
    }
    __except (1) {
        sink(x)
    }
}

Copy link
Contributor Author

@MathiasVP MathiasVP Dec 22, 2022

Choose a reason for hiding this comment

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

Good call. I've added it in 5fa9681. Since this is a C file I had to "throw" using AfxThrowMemoryException.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ahh, but with AfxThrowMemoryException it degenerates to the first case above. Could we add a C++ file with an actual throw?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in a974cb1. It looks like the test behaves as expected: we generate a ThrowValue instruction that correctly transfers flow to the handler block.

Copy link
Contributor

Choose a reason for hiding this comment

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

we generate a ThrowValue instruction that correctly transfers flow to the handler block.

Is that actually what should be happening? I really don't know...

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

So, this indeed seems to be the correct behaviour.

Copy link
Contributor

@jketema jketema left a comment

Choose a reason for hiding this comment

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

LGTM.

@MathiasVP MathiasVP merged commit 98c30b8 into github:main Dec 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C++ no-change-note-required This PR does not need a change note
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants