From 356a5ae5e13b7919f58bff94744e94591c76543e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20Leuth=C3=A4user?= <1417198+max-leuthaeuser@users.noreply.github.com> Date: Thu, 11 Jan 2024 08:05:40 +0100 Subject: [PATCH] [c2cpg] Restore line/column numbers during IASTProblemStatement handling --- .../c2cpg/astcreation/AstForStatementsCreator.scala | 13 ++++++++++++- .../io/joern/c2cpg/macros/MacroHandlingTests.scala | 9 ++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForStatementsCreator.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForStatementsCreator.scala index da090f8749d9..0021e7c6680d 100644 --- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForStatementsCreator.scala +++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstForStatementsCreator.scala @@ -3,6 +3,7 @@ package io.joern.c2cpg.astcreation import io.joern.c2cpg.parser.CdtParser import io.shiftleft.codepropertygraph.generated.ControlStructureTypes import io.joern.x2cpg.{Ast, ValidationMode} +import io.shiftleft.codepropertygraph.generated.nodes.AstNodeNew import io.shiftleft.codepropertygraph.generated.nodes.ExpressionNew import org.eclipse.cdt.core.dom.ast.* import org.eclipse.cdt.core.dom.ast.cpp.* @@ -159,15 +160,25 @@ trait AstForStatementsCreator(implicit withSchemaValidation: ValidationMode) { t } private def astsForProblemStatement(statement: IASTProblemStatement): Seq[Ast] = { + val lineNumber = line(statement) + val columnNumber = column(statement) // We only handle un-parsable macros here for now val isFromMacroExpansion = statement.getProblem.getNodeLocations.exists(_.isInstanceOf[IASTMacroExpansionLocation]) - if (isFromMacroExpansion) { + val asts = if (isFromMacroExpansion) { new CdtParser(config).parse(statement.getRawSignature, Paths.get(statement.getContainingFilename)) match case Some(node) => node.getDeclarations.toIndexedSeq.flatMap(astsForDeclaration) case None => Seq.empty } else { Seq.empty } + // Restore the line/column numbers relative to the statements position + asts.flatMap(_.nodes).foreach { + case astNodeNew: AstNodeNew => + astNodeNew.lineNumber = (lineNumber ++ astNodeNew.lineNumber).reduceOption { case (a, b) => a + (b - 1) } + astNodeNew.columnNumber = (columnNumber ++ astNodeNew.columnNumber).reduceOption(_ + _) + case _ => // do nothing + } + asts } private def astForConditionExpression(expr: IASTExpression, explicitArgumentIndex: Option[Int] = None): Ast = { diff --git a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/macros/MacroHandlingTests.scala b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/macros/MacroHandlingTests.scala index 76e71f01bcee..fd24ecd378c8 100644 --- a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/macros/MacroHandlingTests.scala +++ b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/macros/MacroHandlingTests.scala @@ -277,11 +277,18 @@ class MacroHandlingTests extends CCodeToCpgSuite { val List(localZ) = cpg.local.nameExact("z").l localZ.code shouldBe "int z" localZ.typeFullName shouldBe "int" + localZ.lineNumber shouldBe Some(12) + localZ.columnNumber shouldBe Some(7) val List(zAssignmentCall) = cpg.call.codeExact("z = type_num(x)").l - zAssignmentCall.argument(1).code shouldBe "z" + val zIdentifier = zAssignmentCall.argument(1).asInstanceOf[Identifier] + zIdentifier.code shouldBe "z" + zIdentifier.lineNumber shouldBe Some(12) + zIdentifier.columnNumber shouldBe Some(7) val typeNumCall = zAssignmentCall.argument(2).asInstanceOf[Call] typeNumCall.code shouldBe "type_num(x)" typeNumCall.name shouldBe "type_num" + typeNumCall.lineNumber shouldBe Some(12) + typeNumCall.columnNumber shouldBe Some(11) } } }