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

Implement a throw or raise statement #1733

Draft
wants to merge 25 commits into
base: main
Choose a base branch
from
Draft

Conversation

maximiliankaul
Copy link
Contributor

@maximiliankaul maximiliankaul commented Sep 26, 2024

This PR implements a new ThrowStatement

  • Check the new node. Does it work for all supported languages?
  • Implement EOG
  • Implement DFG
  • Implement all other relevant passes (are there any?)
  • Implement fluent tests

The language specific implementations will be handled in separate PRs:

  • C++ currently uses a UnaryOperator
  • Implement for Python Python: raise #1741
  • Implement for other languages

@maximiliankaul maximiliankaul self-assigned this Sep 26, 2024
Copy link

sonarcloud bot commented Sep 27, 2024

Quality Gate Failed Quality Gate failed

Failed conditions
29.6% Coverage on New Code (required ≥ 75%)

See analysis details on SonarCloud

@maximiliankaul maximiliankaul changed the title Add a RaiseStatement Implement a throw or raise statement Sep 27, 2024
@maximiliankaul maximiliankaul removed their assignment Sep 27, 2024
@maximiliankaul maximiliankaul added the graph-changing This change breaks the current graph structure, i.e. it changes semantic of properties and edges label Sep 27, 2024
@@ -1028,6 +1029,10 @@ open class EvaluationOrderGraphPass(ctx: TranslationContext) : TranslationUnitPa
pushToEOG(stmt)
}

protected fun handleThrowStatement(statement: ThrowStatement) {
TODO("Needs implementing")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
TODO("Needs implementing")
createEOG(statement.exception)
createEOG(statement.cause)
pushToEOG(statement)

Is this the right order of cause and exception?

Copy link
Contributor

Choose a reason for hiding this comment

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

However, I'm not sure how to connect the statement.nextEOG edge to either a CatchStatement (if it's surrounded by a try-catch with a matching catch) the FunctionDeclaration or if this will be subject of this PR at all. Might also be a separate PR to not block other developments.

Copy link
Member

Choose a reason for hiding this comment

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

In theory we might actually have all the necessary information because the EOG runs after the type resolver and we can the get the type information out of the CatchStatement and then match it. If there is no match, we should probably connect the EOG to the function declaration

Copy link
Member

Choose a reason for hiding this comment

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

Ah lol we already have a (working?) implementation in handleThrowOperator! This handles the C++ implementation with a throw unary operator. But we have a problem here... This relies on a TryScope to find a matching TryStatement. But in python we do not open a scope for try since it does not open a new (variable) scoping. This is now the problem that we are mixing scopes for variable visibility and other stuff :(

Additionally, the implementation is not yet handling nested try statements.

node.exception?.let { exc ->
when (exc) {
is CallExpression -> {
handleCallExpression(exc, inferDfgForUnresolvedSymbols)
Copy link
Contributor

Choose a reason for hiding this comment

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

In fact, this should be much easier to handle ;) I guess what you want to do is to generate a DFG from the node.exception to node and maybe also from node.cause to node? This would be simply:

node.exception?.let{ node.prevDFGEdges += it }
node.cause?.let{ node.prevDFGEdges += it }

Since the exception and cause are part of the AST, we will visit and handle them automatically.

* EOG or DFG connections, as it is only of informational purpose, but it doesn't change the
* program behavior.
*/
@Relationship(value = "CAUSE") var causeEdge = astOptionalEdgeOf<Expression>()
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this only be a Reference in all cases? Currently, it's any Expression. Adapt the type or it would make sense to include them in the EOG and DFG.

Anyway, I would recommend adding the cause to the DFG because e.g. if there's sensitive data inside the Exception in the "cause" we may also have this data in the exception raised here; this could violate some policies and the data flow would be lost without the DFG-edge.

For the EOG, it may be useful as well if we can do some more sophisticated things (and it shouldn't harm to have an edge here I guess).

Copy link
Member

Choose a reason for hiding this comment

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

The cause can be any expression, either a call / constructor to a new exception or a reference to an already created one. So, yes it would make sense to have a DFG from cause to throw.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I confused exception with cause... But same applies, in python this can be any expression.

Copy link
Member

Choose a reason for hiding this comment

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

Can we maybe rename this field to parentException, which is a bit more generic?

}

override fun hasArgument(expression: Expression): Boolean {
return when {
Copy link
Contributor

Choose a reason for hiding this comment

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

return exception == expression || cause == expression?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is copy & paste from other nodes to be in line with the style.
Changed.

@KuechA KuechA mentioned this pull request Oct 2, 2024
maximiliankaul and others added 12 commits October 4, 2024 16:02
* Rename `findSymbols` into `lookupSymbolByName`

This PR renames `findSymbols` into `lookupSymbolByName` as a more appropriate name, because it lookups a symbol by its name.

Fixes #1767

* Update cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/ScopeManager.kt

Co-authored-by: KuechA <[email protected]>

* Added documentation

---------

Co-authored-by: KuechA <[email protected]>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Added language trait `HasImplicit Receiver`

This is needed in preparation for #1777 to better handle access to fields/members of a class when an implicit receiver is used.
* Add new function `lookupUniqueTypeSymbolByName`

This adds two new functions `ScopeManager.lookupUniqueTypeSymbolByName` and `Reference.doesReferToType`. This harmonizes a lot of boilerplate code in type resolver, cxx extra pass and resolve ambuigity pass, which were all trying to achieve the same thing.

Fixes #1766

* Fixed issue with Go test, more robust handling of wrapped references

* Addressed code review
… nodes (#1783)

* Make sure to move `typeObservers` from old to new node when replacing nodes

* Added doc for typeobservers
Named expressions in Python use `:=` as operator. Therefore we need to include it in the language definition. Otherwise, the `access` value of a reference will not be set correctly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
graph-changing This change breaks the current graph structure, i.e. it changes semantic of properties and edges
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants