Skip to content

Commit

Permalink
Adding EOG handling for ComprehensionExpression and CollectionCompreh…
Browse files Browse the repository at this point in the history
…ension
  • Loading branch information
konradweiss committed Oct 22, 2024
1 parent 737415c commit e8d7719
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -951,19 +951,54 @@ open class EvaluationOrderGraphPass(ctx: TranslationContext) : TranslationUnitPa

private fun handleComprehensionExpression(node: ComprehensionExpression) {
handleEOG(node.iterable)
// When the iterable contains another element, the variable is evaluated with the
// nextElement. Therefore we ad a
// true edge.
nextEdgeBranch = true
handleEOG(node.variable)
handleEOG(node.predicate)
attachToEOG(node)

// If the conditions evaluated to false, we need to retrieve the next element, therefore
// evaluating the iterable
drawEOGToEntriesOf(currentPredecessors, node.iterable, branchLabel = false)

// If an element was found that fulfills the condition, we move forward
nextEdgeBranch = true
}

private fun handleCollectionComprehension(node: CollectionComprehension) {
// Process the comprehension expressions from 0 to n and connect the EOG of i to i+1.
node.comprehensionExpressions.forEach { handleEOG(it) }
// TODO: Then, the EOG goes to the statement
handleEOG(node.statement)
// TODO: And jumps back to the first thing in the comprehension expressions
var prevComprehensionExpression: ComprehensionExpression? = null
var noMoreElementsEOGExits = listOf<Node>()
node.comprehensionExpressions.forEach {
handleEOG(it)

// [ComprehensionExpression] yields no more elements => EOG:false
val prevComp = prevComprehensionExpression
if (prevComp == null) {
// We handle the EOG:false edges of the outermost comprehensionExpression later,
// they continue the
// path of execution when no more elements are yielded
noMoreElementsEOGExits = currentPredecessors.toList()
} else {
drawEOGToEntriesOf(currentPredecessors, prevComp.iterable, branchLabel = false)
}
prevComprehensionExpression = it

// Then goes to the whole node and we're done
// [ComprehensionExpression] yields and element => EOG:true
nextEdgeBranch = true
}

handleEOG(node.statement)
// After evaluating the statement we
node.comprehensionExpressions.last().let {
drawEOGToEntriesOf(currentPredecessors, it.iterable)
}
currentPredecessors.clear()
currentPredecessors.addAll(noMoreElementsEOGExits)
nextEdgeBranch =
false // This path is followed when the comprehensions yield no more elements
attachToEOG(node)
}

Expand Down Expand Up @@ -1242,4 +1277,13 @@ open class EvaluationOrderGraphPass(ctx: TranslationContext) : TranslationUnitPa
else -> false
}
}

fun drawEOGToEntriesOf(from: List<Node>, toEntriesOf: Node?, branchLabel: Boolean? = null) {

Check warning on line 1281 in cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/EvaluationOrderGraphPass.kt

View check run for this annotation

Codecov / codecov/patch

cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/EvaluationOrderGraphPass.kt#L1281

Added line #L1281 was not covered by tests
val tmpBranchLabel = nextEdgeBranch
branchLabel?.let { nextEdgeBranch = it }
SubgraphWalker.getEOGPathEdges(toEntriesOf).entries.forEach { entrance ->
addMultipleIncomingEOGEdges(from, entrance)
}
nextEdgeBranch = tmpBranchLabel
}
}
47 changes: 0 additions & 47 deletions docs/docs/CPG/specs/eog.md
Original file line number Diff line number Diff line change
Expand Up @@ -655,53 +655,6 @@ Interesting fields:

Scheme:
```mermaid
flowchart LR
classDef outer fill:#fff,stroke:#ddd,stroke-dasharray:5 5;
prev:::outer --EOG--> child1["comprehensionExpressions[0]"]
child1 --EOG--> child2["comprehensionExpressions[n]"]
child2 --EOG--> child3["statement"]
child3 --EOG--> parent(["CollectionComprehension"])
child3 --EOG--> child1
parent --EOG--> next:::outer
parent -.-> child3
parent -.-> child2
parent -.-> child1
```

Alternative:
```mermaid
flowchart LR
classDef outer fill:#fff,stroke:#ddd,stroke-dasharray:5 5;
prev:::outer --EOG--> child1["comprehensionExpressions[0]"]
child1 --EOG--> child2["comprehensionExpressions[n]"]
child2 --EOG--> parent(["CollectionComprehension"])
parent --EOG:true--> child3["statement"]
child3 --EOG--> child1
parent --EOG:false--> next:::outer
parent -.-> child3
parent -.-> child2
parent -.-> child1
```
Alternative2:
```mermaid
flowchart LR
classDef outer fill:#fff,stroke:#ddd,stroke-dasharray:5 5;
prev:::outer --EOG--> child1["comprehensionExpressions[0]"]
child1 --EOG:true--> child2["comprehensionExpressions[n]"]
child1 --EOG:false--> next:::outer
child2 --EOG:true --> parent(["CollectionComprehension"])
child2 --EOG:false--> next:::outer
parent --EOG:true--> child3["statement"]
child3 --EOG--> child1
parent --EOG:false--> next:::outer
parent -.-> child3
parent -.-> child2
parent -.-> child1
```
Alternative3:
```mermaid
flowchart LR
classDef outer fill:#fff,stroke:#ddd,stroke-dasharray:5 5;
prev:::outer --EOG--> child1["comprehensionExpressions[0]"]
Expand Down

0 comments on commit e8d7719

Please sign in to comment.