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

Handle InitializerListExpressions as variables of ComprehensionExpressions in the DFG #2016

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

Conversation

KuechA
Copy link
Contributor

@KuechA KuechA commented Jan 31, 2025

Adapts the ControlFlowSensitiveDFGPass to handle multiple declarations and references in the variable of ComprehensionExpressions. To enhance the readability, the logic is moved to an own function.

Fixes #1957, #2017

It further introduces a new interface HasAccess for Nodes which can be read from or written to. This allows to set the attribute access: AccessValues for more nodes than Reference and it also allows to implement a propagation logic per node class. Currently, the classes Reference, InitializerListExpression and SubscriptExpression implement this interface. It is mainly used to determine the direction of DFG edges.

Copy link

codecov bot commented Jan 31, 2025

Codecov Report

Attention: Patch coverage is 79.59184% with 10 lines in your changes missing coverage. Please review.

Project coverage is 78.24%. Comparing base (6140a2f) to head (44831ec).

Files with missing lines Patch % Lines
...er/aisec/cpg/passes/ControlFlowSensitiveDFGPass.kt 82.60% 3 Missing and 1 partial ⚠️
...tatements/expressions/InitializerListExpression.kt 77.77% 1 Missing and 1 partial ⚠️
...g/graph/statements/expressions/AssignExpression.kt 50.00% 0 Missing and 1 partial ⚠️
...raph/statements/expressions/SubscriptExpression.kt 75.00% 0 Missing and 1 partial ⚠️
...lin/de/fraunhofer/aisec/cpg/graph/types/HasType.kt 50.00% 0 Missing and 1 partial ⚠️
...n/kotlin/de/fraunhofer/aisec/cpg/passes/DFGPass.kt 75.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
Files with missing lines Coverage Δ
...kotlin/de/fraunhofer/aisec/cpg/graph/Interfaces.kt 90.00% <ø> (ø)
...fer/aisec/cpg/graph/statements/ForEachStatement.kt 92.30% <100.00%> (ø)
.../statements/expressions/ComprehensionExpression.kt 59.09% <100.00%> (ø)
...isec/cpg/graph/statements/expressions/Reference.kt 94.28% <100.00%> (ø)
.../cpg/graph/statements/expressions/UnaryOperator.kt 84.21% <100.00%> (+1.45%) ⬆️
...g/graph/statements/expressions/AssignExpression.kt 71.21% <50.00%> (ø)
...raph/statements/expressions/SubscriptExpression.kt 56.41% <75.00%> (+0.85%) ⬆️
...lin/de/fraunhofer/aisec/cpg/graph/types/HasType.kt 77.77% <50.00%> (-1.64%) ⬇️
...n/kotlin/de/fraunhofer/aisec/cpg/passes/DFGPass.kt 83.24% <75.00%> (-0.46%) ⬇️
...tatements/expressions/InitializerListExpression.kt 48.64% <77.77%> (+5.31%) ⬆️
... and 1 more

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@KuechA KuechA marked this pull request as ready for review January 31, 2025 10:47
@KuechA KuechA added DFG blocked Blocked by an external factor labels Feb 2, 2025
@KuechA KuechA marked this pull request as draft February 7, 2025 12:34
@KuechA KuechA marked this pull request as ready for review February 11, 2025 16:25
@KuechA KuechA removed the blocked Blocked by an external factor label Feb 11, 2025
Copy link
Member

@oxisto oxisto left a comment

Choose a reason for hiding this comment

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

Some smaller remarks. In general this looks good, but I wonder whether we should move access to Expression.

@@ -149,3 +149,11 @@ interface HasOverloadedOperation : HasOperatorCode {
*/
val operatorBase: Expression
}

interface HasAccess {
Copy link
Member

Choose a reason for hiding this comment

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

add a small doc string for the interface itself please.

@@ -47,7 +46,7 @@ class ForEachStatement : LoopStatement(), BranchingNode, StatementHolder {
astOptionalEdgeOf<Statement>(
onChanged = { _, new ->
val end = new?.end
if (end is Reference) {
if (end is HasAccess) {
Copy link
Member

Choose a reason for hiding this comment

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

Could be written as (end as? HasAccess)?.access = .... to be consistent with the other assignments.

@@ -72,9 +72,9 @@ class AssignExpression :
}

if (isSimpleAssignment) {
Copy link
Member

Choose a reason for hiding this comment

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

Could be written as

(end as? HasAccess)?.access = if(isSimpleAssignment) {
  AccessValues.WRITE
} else {
  AccessValues.READWRITE
}

@@ -43,7 +44,7 @@ class ComprehensionExpression : Expression(), ArgumentHolder {
of = ProblemExpression("Missing variableEdge in ${this::class}"),
onChanged = { _, new ->
val end = new?.end
if (end is Reference) {
if (end is HasAccess) {
Copy link
Member

Choose a reason for hiding this comment

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

(it.end as? HasAccess)?.access to be consistent

* Is this reference used for writing data instead of just reading it? Determines dataflow
* direction
*/
var access: AccessValues
Copy link
Member

Choose a reason for hiding this comment

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

On second thought. Wouldn't it make sense to just implements this on all Expression nodes? The memory overhead is probably negligible and we would remove a lot of ugly as? HasAccess casts. Basically this should apply to all expressions.

}
}

// state.push(writtenToIt, PowersetLattice(identitySetOf(currentNode.iterable)))
Copy link
Member

Choose a reason for hiding this comment

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

leftover?

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