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

Replace UnaryOperator("throw") with ThrowStatement for CXX #1815

Merged
merged 9 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -572,8 +572,8 @@ val Node?.forLoops: List<ForStatement>
val Node?.trys: List<TryStatement>
get() = this.allChildren()

/** Returns all [ThrowStatement] child edges in this graph, starting with this [Node]. */
val Node?.throws: List<ThrowStatement>
/** Returns all [ThrowExpression] child edges in this graph, starting with this [Node]. */
val Node?.throws: List<ThrowExpression>
get() = this.allChildren()

/** Returns all [ForEachStatement] child edges in this graph, starting with this [Node]. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,14 +358,14 @@ fun MetadataProvider.newLookupScopeStatement(
}

/**
* Creates a new [ThrowStatement]. The [MetadataProvider] receiver will be used to fill different
* Creates a new [ThrowExpression]. The [MetadataProvider] receiver will be used to fill different
* meta-data using [Node.applyMetadata]. Calling this extension function outside of Kotlin requires
* an appropriate [MetadataProvider], such as a [LanguageFrontend] as an additional prepended
* argument.
*/
@JvmOverloads
fun MetadataProvider.newThrowStatement(rawNode: Any? = null): ThrowStatement {
val node = ThrowStatement()
fun MetadataProvider.newThrowStatement(rawNode: Any? = null): ThrowExpression {
val node = ThrowExpression()
node.applyMetadata(this, EMPTY_NAME, rawNode, true)

log(node)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1457,11 +1457,11 @@ infix fun Expression.assignAsExpr(rhs: AssignExpression.() -> Unit): AssignExpre
}

/**
* Creates a new [ThrowStatement] in the Fluent Node DSL and adds it to the nearest enclosing
* Creates a new [ThrowExpression] in the Fluent Node DSL and adds it to the nearest enclosing
* [StatementHolder].
*/
context(LanguageFrontend<*, *>, Holder<out Node>)
infix fun Expression.`throw`(init: (ThrowStatement.() -> Unit)?): ThrowStatement {
infix fun Expression.`throw`(init: (ThrowExpression.() -> Unit)?): ThrowExpression {
val node = (this@LanguageFrontend).newThrowStatement()
if (init != null) init(node)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,20 @@ import java.util.Objects
import org.apache.commons.lang3.builder.ToStringBuilder
import org.neo4j.ogm.annotation.Relationship

/** Represents a `throw` or `raise` statement. */
class ThrowStatement : Statement(), ArgumentHolder {
/** Represents a `throw` or `raise` statement/expression. */
class ThrowExpression : Expression(), ArgumentHolder {

/** The exception object to be raised. */
@Relationship(value = "EXCEPTION") var exceptionEdge = astOptionalEdgeOf<Expression>()
var exception by unwrapping(ThrowStatement::exceptionEdge)
var exception by unwrapping(ThrowExpression::exceptionEdge)

/**
* Some languages (Python) can add a parent exception (or `cause`) to indicate that an exception
* was raised while handling another exception.
*/
@Relationship(value = "PARENT_EXCEPTION")
var parentExceptionEdge = astOptionalEdgeOf<Expression>()
var parentException by unwrapping(ThrowStatement::parentExceptionEdge)
var parentException by unwrapping(ThrowExpression::parentExceptionEdge)

override fun addArgument(expression: Expression) {
when {
Expand Down Expand Up @@ -75,7 +75,7 @@ class ThrowStatement : Statement(), ArgumentHolder {

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is ThrowStatement) return false
if (other !is ThrowExpression) return false
return super.equals(other) &&
exception == other.exception &&
parentException == other.parentException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class DFGPass(ctx: TranslationContext) : ComponentPass(ctx) {
is ForStatement -> handleForStatement(node)
is SwitchStatement -> handleSwitchStatement(node)
is IfStatement -> handleIfStatement(node)
is ThrowStatement -> handleThrowStatement(node)
is ThrowExpression -> handleThrowStatement(node)
// Declarations
is FieldDeclaration -> handleFieldDeclaration(node)
is FunctionDeclaration -> handleFunctionDeclaration(node, functionSummaries)
Expand Down Expand Up @@ -169,8 +169,8 @@ class DFGPass(ctx: TranslationContext) : ComponentPass(ctx) {
comprehension.predicate?.let { comprehension.prevDFG += it }
}

/** Handle a [ThrowStatement]. The exception and parent exception flow into the node. */
protected fun handleThrowStatement(node: ThrowStatement) {
/** Handle a [ThrowExpression]. The exception and parent exception flow into the node. */
protected fun handleThrowStatement(node: ThrowExpression) {
node.exception?.let { node.prevDFGEdges += it }
node.parentException?.let { node.prevDFGEdges += it }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ open class EvaluationOrderGraphPass(ctx: TranslationContext) : TranslationUnitPa
map[LookupScopeStatement::class.java] = {
handleLookupScopeStatement(it as LookupScopeStatement)
}
map[ThrowStatement::class.java] = { handleThrowStatement(it as ThrowStatement) }
map[ThrowExpression::class.java] = { handleThrowStatement(it as ThrowExpression) }
}

protected fun doNothing() {
Expand Down Expand Up @@ -1124,7 +1124,7 @@ open class EvaluationOrderGraphPass(ctx: TranslationContext) : TranslationUnitPa
}

/** Calls [handleThrowOperator]. */
protected fun handleThrowStatement(statement: ThrowStatement) {
protected fun handleThrowStatement(statement: ThrowExpression) {
handleThrowOperator(
statement,
statement.exception?.type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import de.fraunhofer.aisec.cpg.GraphExamples.Companion.testFrontend
import de.fraunhofer.aisec.cpg.TranslationConfiguration
oxisto marked this conversation as resolved.
Show resolved Hide resolved
import de.fraunhofer.aisec.cpg.frontends.TestLanguage
import de.fraunhofer.aisec.cpg.graph.builder.*
import de.fraunhofer.aisec.cpg.graph.statements.ThrowStatement
import de.fraunhofer.aisec.cpg.graph.statements.ThrowExpression
import de.fraunhofer.aisec.cpg.graph.statements.expressions.Block
import de.fraunhofer.aisec.cpg.graph.statements.expressions.CallExpression
import de.fraunhofer.aisec.cpg.test.assertLocalName
Expand Down Expand Up @@ -69,21 +69,21 @@ class ThrowStatementTest {
assertIs<Block>(body)

val emptyThrow = body.statements.getOrNull(0)
assertIs<ThrowStatement>(emptyThrow)
assertIs<ThrowExpression>(emptyThrow)
println(emptyThrow.toString()) // This is only here to simulate a higher test coverage
assertNull(emptyThrow.exception)
assertTrue(emptyThrow.prevDFG.isEmpty())

val throwWithExc = body.statements.getOrNull(1)
assertIs<ThrowStatement>(throwWithExc)
assertIs<ThrowExpression>(throwWithExc)
println(throwWithExc.toString()) // This is only here to simulate a higher test coverage
val throwCall = throwWithExc.exception
assertIs<CallExpression>(throwCall)
assertLocalName("SomeError", throwCall)
assertEquals(setOf<Node>(throwCall), throwWithExc.prevDFG.toSet())

val throwWithExcAndParent = body.statements.getOrNull(2)
assertIs<ThrowStatement>(throwWithExcAndParent)
assertIs<ThrowExpression>(throwWithExcAndParent)
println(
throwWithExcAndParent.toString()
) // This is only here to simulate a higher test coverage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ package de.fraunhofer.aisec.cpg.graph.edges.flows
import de.fraunhofer.aisec.cpg.GraphExamples.Companion.prepareThrowDFGTest
import de.fraunhofer.aisec.cpg.frontends.TestLanguageFrontend
import de.fraunhofer.aisec.cpg.graph.*
import de.fraunhofer.aisec.cpg.graph.statements.ThrowStatement
import de.fraunhofer.aisec.cpg.graph.statements.ThrowExpression
import de.fraunhofer.aisec.cpg.graph.statements.expressions.Block
import de.fraunhofer.aisec.cpg.graph.statements.expressions.CallExpression
import kotlin.collections.firstOrNull
Expand Down Expand Up @@ -118,7 +118,7 @@ class DataflowTest {
assertIs<Block>(body)

val throwStmt = body.statements.getOrNull(1)
assertIs<ThrowStatement>(throwStmt)
assertIs<ThrowExpression>(throwStmt)
assertNotNull(throwStmt.exception)
val throwCall = throwStmt.exception
assertIs<CallExpression>(throwCall)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,8 @@ class ExpressionHandler(lang: CXXLanguageFrontend) :
// need to information about the parenthesis.
return input as Expression
}
IASTUnaryExpression.op_throw -> operatorCode = "throw"
IASTUnaryExpression.op_throw ->
return newThrowStatement(rawNode = ctx).apply { this.exception = input }
IASTUnaryExpression.op_typeid -> operatorCode = "typeid"
IASTUnaryExpression.op_alignOf -> operatorCode = "alignof"
IASTUnaryExpression.op_sizeofParameterPack -> operatorCode = "sizeof..."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ class StatementHandler(frontend: PythonLanguageFrontend) :

/**
* Translates a Python [`Raise`](https://docs.python.org/3/library/ast.html#ast.Raise) into a
* [ThrowStatement].
* [ThrowExpression].
*/
private fun handleRaise(node: Python.AST.Raise): ThrowStatement {
private fun handleRaise(node: Python.AST.Raise): ThrowExpression {
val ret = newThrowStatement(rawNode = node)
node.exc?.let { ret.exception = frontend.expressionHandler.handle(it) }
node.cause?.let { ret.parentException = frontend.expressionHandler.handle(it) }
Expand Down
Loading