From 3924bb5a0aa405f6232662312b7d371965e7d3b0 Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Mon, 1 Jul 2024 13:14:35 +0200 Subject: [PATCH] Adding new operator call expression --- .../aisec/cpg/graph/ExpressionBuilder.kt | 9 ++++----- .../expressions/OperatorCallExpression.kt | 15 +++++++++++++-- .../fraunhofer/aisec/cpg/passes/SymbolResolver.kt | 7 ++----- .../aisec/cpg/frontends/cxx/CXXDeclarationTest.kt | 4 ++-- .../resources/cxx/operators/member_access.cpp | 2 ++ 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/ExpressionBuilder.kt b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/ExpressionBuilder.kt index 9120c8140c..61a6bf7a0c 100644 --- a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/ExpressionBuilder.kt +++ b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/ExpressionBuilder.kt @@ -293,11 +293,10 @@ fun MetadataProvider.newOperatorCallExpression( rawNode: Any? = null ): OperatorCallExpression { val node = OperatorCallExpression() - node.applyMetadata( - this, - operatorCode, - rawNode - ) + node.applyMetadata(this, operatorCode, rawNode) + + node.operatorCode = operatorCode + node.callee = callee log(node) return node diff --git a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/statements/expressions/OperatorCallExpression.kt b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/statements/expressions/OperatorCallExpression.kt index a243c95093..211f1ff063 100644 --- a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/statements/expressions/OperatorCallExpression.kt +++ b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/graph/statements/expressions/OperatorCallExpression.kt @@ -25,6 +25,7 @@ */ package de.fraunhofer.aisec.cpg.graph.statements.expressions +import de.fraunhofer.aisec.cpg.graph.HasBase import de.fraunhofer.aisec.cpg.graph.HasOperatorCode import de.fraunhofer.aisec.cpg.graph.Name import de.fraunhofer.aisec.cpg.graph.declarations.OperatorDeclaration @@ -34,11 +35,21 @@ import de.fraunhofer.aisec.cpg.graph.declarations.OperatorDeclaration * In this case, we replace the original [BinaryOperator] with an [OperatorCallExpression], which * points to its respective [OperatorDeclaration]. */ -class OperatorCallExpression : CallExpression(), HasOperatorCode { +class OperatorCallExpression : CallExpression(), HasOperatorCode, HasBase { - override val operatorCode: String? = null + override var operatorCode: String? = null override var name: Name get() = Name(operatorCode ?: "") set(_) {} + + /** + * The base object. This is basically a shortcut to accessing the base of the [callee], if it + * has one (i.e., if it implements [HasBase]). This is the case for example, if it is a + * [MemberExpression]. + */ + override val base: Expression? + get() { + return (callee as? HasBase)?.base + } } diff --git a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/SymbolResolver.kt b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/SymbolResolver.kt index 29e6365924..772cccd1e5 100644 --- a/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/SymbolResolver.kt +++ b/cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/passes/SymbolResolver.kt @@ -448,10 +448,6 @@ open class SymbolResolver(ctx: TranslationContext) : ComponentPass(ctx) { .filterIsInstance() .singleOrNull() - // We unfortunately, have no direct access to the AST parent, but this is a very good - // heuristic to get it - var parent = reference.base.prevEOG.singleOrNull() - if (op != null) { type = op.returnTypes.singleOrNull()?.root ?: unknownType() @@ -460,7 +456,8 @@ open class SymbolResolver(ctx: TranslationContext) : ComponentPass(ctx) { newMemberExpression(op.name, reference.base, operatorCode = ".") .implicit(op.name.localName, location = reference.location) ref.refersTo = op - var call = newOperatorCallExpression(operatorCode = ".", ref).codeAndLocationFrom(ref) + var call = + newOperatorCallExpression(operatorCode = "->", ref).codeAndLocationFrom(ref) call.invokes = listOf(op) // Make the call our new base diff --git a/cpg-language-cxx/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/cxx/CXXDeclarationTest.kt b/cpg-language-cxx/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/cxx/CXXDeclarationTest.kt index 8b68fc2ded..13727f0501 100644 --- a/cpg-language-cxx/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/cxx/CXXDeclarationTest.kt +++ b/cpg-language-cxx/src/test/kotlin/de/fraunhofer/aisec/cpg/frontends/cxx/CXXDeclarationTest.kt @@ -30,7 +30,7 @@ import de.fraunhofer.aisec.cpg.graph.declarations.FunctionDeclaration import de.fraunhofer.aisec.cpg.graph.statements.ReturnStatement import de.fraunhofer.aisec.cpg.graph.statements.expressions.BinaryOperator import de.fraunhofer.aisec.cpg.graph.statements.expressions.Block -import de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberCallExpression +import de.fraunhofer.aisec.cpg.graph.statements.expressions.OperatorCallExpression import de.fraunhofer.aisec.cpg.graph.statements.expressions.UnaryOperator import de.fraunhofer.aisec.cpg.graph.types.FunctionPointerType import de.fraunhofer.aisec.cpg.test.* @@ -280,7 +280,7 @@ class CXXDeclarationTest { // we should now have an implicit call to our operator in-between "p" and "size" val opCall = sizeRef.base assertNotNull(opCall) - assertIs(opCall) + assertIs(opCall) assertEquals(p, opCall.base) assertInvokes(opCall, op) } diff --git a/cpg-language-cxx/src/test/resources/cxx/operators/member_access.cpp b/cpg-language-cxx/src/test/resources/cxx/operators/member_access.cpp index c88e7fa0f6..5136efc645 100644 --- a/cpg-language-cxx/src/test/resources/cxx/operators/member_access.cpp +++ b/cpg-language-cxx/src/test/resources/cxx/operators/member_access.cpp @@ -19,4 +19,6 @@ class Proxy { int main() { Proxy p; int size = p->size; + + // int another_size = p.operator->()->size; } \ No newline at end of file