Skip to content

Commit

Permalink
Added testcase for unwrapReference
Browse files Browse the repository at this point in the history
  • Loading branch information
oxisto committed Nov 24, 2023
1 parent acc0b71 commit aa8615c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -662,3 +662,25 @@ private fun Node.eogDistanceTo(to: Node): Int {

return i
}

/**
* This is a small utility function to "unwrap" a [Reference] that it is wrapped in (multiple)
* [Expression] nodes. This will only work on expression that only have one "argument" (such as a
* unary operator), in order to avoid ambiguous results. This can be useful for data-flow analysis,
* if you want to quickly retrieve the reference that is affected by an operation. For example in
* C++ it is common to take an address of a variable and cast it into an appropriate type:
* ```cpp
* int64_t addr = (int64_t) &a;
* ```
*
* When called on the right-hand side of this assignment, this function will return `a`.
*/
fun Expression?.unwrapReference(): Reference? {
return when {
this is Reference -> this
this is UnaryOperator && (this.operatorCode == "*" || this.operatorCode == "&") ->
this.input.unwrapReference()
this is CastExpression -> this.expression.unwrapReference()
else -> null
}
}
16 changes: 0 additions & 16 deletions cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/helpers/Util.kt
Original file line number Diff line number Diff line change
Expand Up @@ -405,20 +405,4 @@ object Util {
ENTRIES,
EXITS
}

fun unwrapReference(node: Node?): Reference? {
return if (node is Reference) node
else if (node is UnaryOperator && (node.operatorCode == "*" || node.operatorCode == "&"))
unwrapReference(node.input)
else if (node is CastExpression) unwrapReference(node.expression)
else if (
node is BinaryOperator &&
(node.operatorCode == "&" || node.operatorCode == "*") &&
node.lhs is CastExpression &&
(node.lhs as CastExpression).expression is ProblemExpression
)
// TODO: This is only a hotfix for a bug in the language frontend.
unwrapReference(node.rhs)
else null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ package de.fraunhofer.aisec.cpg.graph

import de.fraunhofer.aisec.cpg.*
import de.fraunhofer.aisec.cpg.frontends.TestLanguage
import de.fraunhofer.aisec.cpg.frontends.TestLanguageFrontend
import de.fraunhofer.aisec.cpg.graph.declarations.FunctionDeclaration
import de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration
import de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration
Expand Down Expand Up @@ -348,6 +349,20 @@ class ShortcutsTest {
assertEquals(3, (paramPassed.last() as? Literal<*>)?.value)
}

@Test
fun testUnwrapReference() {
with(TestLanguageFrontend()) {
val a = newReference("a")
val op = newUnaryOperator("&", prefix = true, postfix = false)
op.input = a
val cast = newCastExpression()
cast.castType = objectType("int64")
cast.expression = op

assertEquals(a, cast.unwrapReference())
}
}

private lateinit var shortcutClassResult: TranslationResult

@BeforeAll
Expand Down

0 comments on commit aa8615c

Please sign in to comment.