Skip to content
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

Brodes/seh flow overhaul2 #17676

Open
wants to merge 24 commits into
base: main
Choose a base branch
from

Conversation

bdrodes
Copy link
Contributor

@bdrodes bdrodes commented Oct 7, 2024

Overhaul of try/catch to support differentiating SEH vs C++ exception handling in IR generation.

@github-actions github-actions bot added the C++ label Oct 7, 2024
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 20 potential problems in the proposed changes. Check the Files changed tab for more details.

Copy link
Contributor

@MathiasVP MathiasVP left a comment

Choose a reason for hiding this comment

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

Some initial comments. I haven't looked through TranslatedFunction, TranslatedInitialization, or TranslatedStmt yet.

Copy link
Contributor

@MathiasVP MathiasVP left a comment

Choose a reason for hiding this comment

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

Some more IR construction comments. I think I've looked through all IR construction files now 🤞

Copy link
Contributor

@MathiasVP MathiasVP left a comment

Choose a reason for hiding this comment

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

Final rounds of comments. Once these are resolved I suggest you pull it out of draft and we can pass the review torch to the GitHub folks 😄

@@ -3437,8 +3460,7 @@ class TranslatedVarArg extends TranslatedNonConstantExpr {

final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
tag = VarArgsVAListLoadTag() and
kind instanceof GotoEdge and
result = this.getInstruction(VarArgsArgAddressTag())
(kind instanceof GotoEdge and result = this.getInstruction(VarArgsArgAddressTag()))
Copy link
Contributor

Choose a reason for hiding this comment

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

This parenthesis here is also superfluous 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.

So much for the formatting tool fixing that automatically.

Copy link
Contributor

@MathiasVP MathiasVP Oct 23, 2024

Choose a reason for hiding this comment

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

😅 Yeah, the autoformatter doesn't remove all superfluous parentheses (because that's apparently a super hard problem in general). By the way, it's still complaining about missing autoformat in a couple of places, though:

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll would change by autoformatting.
cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll would change by autoformatting.
cpp/ql/lib/semmle/code/cpp/models/implementations/StructuredExceptionHandling.qll would change by autoformatting.
cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll would change by autoformatting.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Comment on lines +6 to +7
* unconditional or non-throwing. IR generation will enforce
* the most strict interpretation.
Copy link
Contributor

Choose a reason for hiding this comment

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

Where does this enforcement happen?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

* the most strict interpretation.
*/
class DefaultSEHExceptionBehavior extends ThrowingFunction {
DefaultSEHExceptionBehavior() { this = any(Function f) }
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need this charpred as ThrowingFunction is already a Function (which Code Scanning is also telling us 🎉)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let me ask this. It is currently defined as a function yes, but in my refactor of this concept I had intended that an ExceptionAnnotation can be on any expression. Hence, this char pred exists for that concept, but you are right it is not needed given I didn't think I could swing that concept for this pr. The question is, given I would hope it could generalize, should the char pred be defensive?

Copy link
Contributor

@MathiasVP MathiasVP Oct 23, 2024

Choose a reason for hiding this comment

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

I'm fine with leaving it here. Although, I don't think we'll ever generalize ThrowingFunction to not be a function since that would probably be a bit confusing. Rather, if we generalize it to ThrowingExpr I think we'd keep ThrowingFunction as a special case that extends both Function and ThrowingExpr.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved the char pred up to ThrowingFunction, an abstract, as that makes more sense, However, removing the char pred does result in a warning. Apparently extending an abstract class without specifying a char pred is a no no? What do you suggest? Define one with "any()"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I went with this 'any' approach, but depending on your comments I can revert it.

cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll Outdated Show resolved Hide resolved
@bdrodes bdrodes marked this pull request as ready for review October 23, 2024 19:33
@bdrodes bdrodes requested a review from a team as a code owner October 23, 2024 19:33
@bdrodes
Copy link
Contributor Author

bdrodes commented Oct 23, 2024

@MathiasVP I realize I need a change log, but previously I put change logs under src/change-notes. For libraries, I see lib/change-notes and a released directory. Do I put it at the same level of released or should there be another sub directory? I'm moving to ready to review while we figure that out.

@MathiasVP
Copy link
Contributor

Yeah, the "unreleased" change notes goes in this folder: https://github.com/github/codeql/tree/main/cpp/ql/lib/change-notes

Then, as part of the release process, those files will be moved into the "released" folder.

@jketema
Copy link
Contributor

jketema commented Oct 24, 2024

@bdrodes Could you please fix all the QL-for-QL warnings except the redundant import ones?

…oft/codeql into brodes/seh_flow_overhaul2

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
@bdrodes
Copy link
Contributor Author

bdrodes commented Oct 24, 2024

@jketema or @MathiasVP I'm not sure what is required for the newtype qldocs, here's what's in the code, but it is still complaining:

image

@MathiasVP
Copy link
Contributor

You need to use QLDoc on the branches as well:

/** Structure Exception Handling (SEH) exception */
TSEHException() or
/** C++ exception */
TCxxException()

By the way, I've seen "Structure Exception Handling" in multiple places. They should probably be fixed to be "Structured Exception Handling".

@bdrodes
Copy link
Contributor Author

bdrodes commented Oct 24, 2024

Good find @MathiasVP . Fixing...

@bdrodes
Copy link
Contributor Author

bdrodes commented Oct 24, 2024

@jketema , I think that covers your asks for the ql-for-ql with my last push.

@jketema
Copy link
Contributor

jketema commented Oct 24, 2024

@jketema , I think that covers your asks for the ql-for-ql with my last push.

I still see quite a large number of them when I look at the changes.

@bdrodes
Copy link
Contributor Author

bdrodes commented Oct 24, 2024

@jketema , my misunderstanding, I thought I was reviewing the actions warnings. @MathiasVP set me straight where to look. I'll get back to you.

@bdrodes
Copy link
Contributor Author

bdrodes commented Oct 24, 2024

@jketema , altered all the isSEH to isSeh to be in compliance with convention. I think that got rid of the warnings.

@jketema
Copy link
Contributor

jketema commented Oct 25, 2024

Note that this is currently breaking 100s of tests.


private newtype TEdgeKind =
TGotoEdge() or // Single successor (including fall-through)
TTrueEdge() or // 'true' edge of conditional branch
TFalseEdge() or // 'false' edge of conditional branch
TExceptionEdge() or // Thrown exception
TExceptionEdge(Boolean isSeh) or // Thrown exception, true for SEH exceptions, false otherwise
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the reason for doing with with a boolean instead of just having two separate kinds of edges (one for normal exceptions and one for SEH exceptions)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We want a single edge concept for all exceptions. A problem we have had generally with SEH vs traditional is the concept has been handled by different mechanisms making it error prone to do anything with exceptions as it is easy to forget the 'other' exception.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants