Repository: joernio/joern (scala)

Issue:
oldc vs newc Parsing-Difference: indirection on call
I noticed that the c code produces different results with the old and new c parser

```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef long unsigned int (*hStrLenFunc)(const char *str);

int main()
{
    hStrLenFunc strLenFunc = &strlen;
    return (*strLenFunc)("123");
}
```

newc:
```scala
joern> cpg.method("main").call.l 
res26: List[Call] = List(
  Call(
    id -> 3074457345618261028L,
    argumentIndex -> 2,
    argumentName -> None,
    code -> "strLenFunc = &strlen",
    columnNumber -> Some(value = 16),
    dispatchType -> "STATIC_DISPATCH",
    dynamicTypeHintFullName -> ArraySeq(),
    lineNumber -> Some(value = 9),
    methodFullName -> "<operator>.assignment",
    name -> "<operator>.assignment",
    order -> 2,
    signature -> "TODO",
    typeFullName -> "<empty>"
  ),
  Call(
    id -> 3074457345618261030L,
    argumentIndex -> 2,
    argumentName -> None,
    code -> "&strlen",
    columnNumber -> Some(value = 29),
    dispatchType -> "STATIC_DISPATCH",
    dynamicTypeHintFullName -> ArraySeq(),
    lineNumber -> Some(value = 9),
    methodFullName -> "<operator>.addressOf",
    name -> "<operator>.addressOf",
    order -> 2,
    signature -> "TODO",
    typeFullName -> "<empty>"
  ),
  Call(
    id -> 3074457345618261033L,
    argumentIndex -> 1,
    argumentName -> None,
    code -> "(*strLenFunc)(\"123\")",
    columnNumber -> Some(value = 11),
    dispatchType -> "STATIC_DISPATCH",
    dynamicTypeHintFullName -> ArraySeq(),
    lineNumber -> Some(value = 10),
    methodFullName -> "",
    name -> "",
    order -> 1,
    signature -> "TODO",
    typeFullName -> "<empty>"
  ),
  Call(
    id -> 3074457345618261034L,
    argumentIndex -> 0,
    argumentName -> None,
    code -> "*strLenFunc",
    columnNumber -> Some(value = 12),
    dispatchType -> "STATIC_DISPATCH",
    dynamicTypeHintFullName -> ArraySeq(),
    lineNumber -> Some(value = 10),
    methodFullName -> "<operator>.indirection",
    name -> "<operator>.indirection",
    order -> 0,
    signature -> "TODO",
    typeFullName -> "<empty>"
  )
)
```

oldc:
```scala
joern> cpg.method("main").call.l 
res3: List[Call] = List(
  Call(
    id -> 1000463L,
    argumentIndex -> 2,
    argumentName -> None,
    code -> "strLenFunc = &strlen",
    columnNumber -> Some(value = 16),
    dispatchType -> "STATIC_DISPATCH",
    dynamicTypeHintFullName -> ArraySeq(),
    lineNumber -> Some(value = 9),
    methodFullName -> "<operator>.assignment",
    name -> "<operator>.assignment",
    order -> 2,
    signature -> "TODO",
    typeFullName -> "<empty>"
  ),
  Call(
    id -> 1000465L,
    argumentIndex -> 2,
    argumentName -> None,
    code -> "&strlen",
    columnNumber -> Some(value = 29),
    dispatchType -> "STATIC_DISPATCH",
    dynamicTypeHintFullName -> ArraySeq(),
    lineNumber -> Some(value = 9),
    methodFullName -> "<operator>.addressOf",
    name -> "<operator>.addressOf",
    order -> 2,
    signature -> "TODO",
    typeFullName -> "<empty>"
  ),
  Call(
    id -> 1000468L,
    argumentIndex -> 1,
    argumentName -> None,
    code -> "(*strLenFunc)(\"123\")",
    columnNumber -> Some(value = 11),
    dispatchType -> "STATIC_DISPATCH",
    dynamicTypeHintFullName -> ArraySeq(),
    lineNumber -> Some(value = 10),
    methodFullName -> "*strLenFunc",
    name -> "*strLenFunc",
    order -> 1,
    signature -> "TODO",
    typeFullName -> "<empty>"
  )
)
```

As you can see, the old one showed a more or less correct `methodFullName` but the new one has nothing for the `methodFullName`. What I like about the new parser, is that it clearly shows the indirection which you can't see in the old one.

Pull request:
Fixes: https://github.com/joernio/joern/issues/777

Patch:
diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForExpressionsCreator.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForExpressionsCreator.scala
index f7e3593b8908..dd058e5c8dd7 100644
--- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForExpressionsCreator.scala
+++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForExpressionsCreator.scala
@@ -1,6 +1,6 @@
 package io.joern.c2cpg.astcreation
 
-import io.shiftleft.codepropertygraph.generated.nodes.{NewBlock, NewIdentifier, NewMethodRef}
+import io.shiftleft.codepropertygraph.generated.nodes.{NewBlock, NewCall, NewIdentifier, NewMethodRef}
 import io.shiftleft.codepropertygraph.generated.{DispatchTypes, Operators}
 import io.shiftleft.x2cpg.Ast
 import org.eclipse.cdt.core.dom.ast._
@@ -97,6 +97,8 @@ trait AstForExpressionsCreator {
         (DispatchTypes.STATIC_DISPATCH, rec.root.get.asInstanceOf[NewMethodRef].methodFullName)
       case _ if rec.root.exists(_.isInstanceOf[NewIdentifier]) =>
         (DispatchTypes.STATIC_DISPATCH, rec.root.get.asInstanceOf[NewIdentifier].name)
+      case _ if rec.root.exists(_.isInstanceOf[NewCall]) =>
+        (DispatchTypes.STATIC_DISPATCH, rec.root.get.asInstanceOf[NewCall].code)
       case reference: IASTIdExpression =>
         (DispatchTypes.STATIC_DISPATCH, nodeSignature(reference))
       case _ =>


Test patch:
diff --git a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/passes/AstCreationPassTests.scala b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/passes/AstCreationPassTests.scala
index 8d800e88d3b5..cacb435aa6bd 100644
--- a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/passes/AstCreationPassTests.scala
+++ b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/passes/AstCreationPassTests.scala
@@ -932,6 +932,21 @@ class AstCreationPassTests
       }
     }
 
+    "be correct for indirection on call" in TestAstOnlyFixture(
+      """
+       |typedef long unsigned int (*hStrLenFunc)(const char *str);
+       |int main() {
+       |  hStrLenFunc strLenFunc = &strlen;
+       |  return (*strLenFunc)("123");
+       |}
+      """.stripMargin) { cpg =>
+      inside(cpg.method.name("main").ast.isCall.codeExact("(*strLenFunc)(\"123\")").l) {
+        case List(call) =>
+          call.name shouldBe "*strLenFunc"
+          call.methodFullName shouldBe "*strLenFunc"
+      }
+    }
+
     "be correct for sizeof operator on identifier with brackets" in TestAstOnlyFixture(
       """
         |void method() {