diff --git a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala index 7159d6c0315..eb2a0390669 100644 --- a/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala +++ b/joern-cli/frontends/c2cpg/src/main/scala/io/joern/c2cpg/astcreation/AstCreatorHelper.scala @@ -18,11 +18,13 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTArrayRangeDesignator import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation import org.eclipse.cdt.internal.core.model.ASTStringUtil import java.nio.file.{Path, Paths} import scala.annotation.nowarn import scala.collection.mutable +import scala.util.Try object AstCreatorHelper { @@ -155,13 +157,18 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As } } + private def safeGetEvaluation(expr: ICPPASTExpression): Option[ICPPEvaluation] = { + // In case of unresolved includes etc. this may fail throwing an unrecoverable exception + Try(expr.getEvaluation).toOption + } + @nowarn protected def typeFor(node: IASTNode, stripKeywords: Boolean = true): String = { import org.eclipse.cdt.core.dom.ast.ASTSignatureUtil.getNodeSignature node match { case f: CPPASTFieldReference => - f.getFieldOwner.getEvaluation match { - case evaluation: EvalBinding => cleanType(evaluation.getType.toString, stripKeywords) + safeGetEvaluation(f.getFieldOwner) match { + case Some(evaluation: EvalBinding) => cleanType(evaluation.getType.toString, stripKeywords) case _ => cleanType(ASTTypeUtil.getType(f.getFieldOwner.getExpressionType), stripKeywords) } case f: IASTFieldReference => @@ -184,10 +191,10 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As }.mkString s"$tpe$arr" case s: CPPASTIdExpression => - s.getEvaluation match { - case evaluation: EvalMemberAccess => + safeGetEvaluation(s) match { + case Some(evaluation: EvalMemberAccess) => cleanType(evaluation.getOwnerType.toString, stripKeywords) - case evalBinding: EvalBinding => + case Some(evalBinding: EvalBinding) => evalBinding.getBinding match { case m: CPPMethod => cleanType(fullName(m.getDefinition)) case _ => cleanType(ASTTypeUtil.getNodeType(s), stripKeywords) @@ -277,16 +284,20 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As protected def fullName(node: IASTNode): String = { val qualifiedName: String = node match { - case d: CPPASTIdExpression if d.getEvaluation.isInstanceOf[EvalBinding] => - val evaluation = d.getEvaluation.asInstanceOf[EvalBinding] - evaluation.getBinding match { - case f: CPPFunction if f.getDeclarations != null => - f.getDeclarations.headOption.map(n => s"${fullName(n)}").getOrElse(f.getName) - case f: CPPFunction if f.getDefinition != null => - s"${fullName(f.getDefinition)}" - case other => - other.getName + case d: CPPASTIdExpression => + safeGetEvaluation(d) match { + case Some(evalBinding: EvalBinding) => + evalBinding.getBinding match { + case f: CPPFunction if f.getDeclarations != null => + f.getDeclarations.headOption.map(n => s"${fullName(n)}").getOrElse(f.getName) + case f: CPPFunction if f.getDefinition != null => + s"${fullName(f.getDefinition)}" + case other => + other.getName + } + case _ => ASTStringUtil.getSimpleName(d.getName) } + case alias: ICPPASTNamespaceAlias => alias.getMappingName.toString case namespace: ICPPASTNamespaceDefinition if ASTStringUtil.getSimpleName(namespace.getName).nonEmpty => s"${fullName(namespace.getParent)}.${ASTStringUtil.getSimpleName(namespace.getName)}" @@ -348,15 +359,18 @@ trait AstCreatorHelper(implicit withSchemaValidation: ValidationMode) { this: As .isEmpty && f.getDeclarator.getNestedDeclarator != null => shortName(f.getDeclarator.getNestedDeclarator) case f: IASTFunctionDefinition => ASTStringUtil.getSimpleName(f.getDeclarator.getName) - case d: CPPASTIdExpression if d.getEvaluation.isInstanceOf[EvalBinding] => - val evaluation = d.getEvaluation.asInstanceOf[EvalBinding] - evaluation.getBinding match { - case f: CPPFunction if f.getDeclarations != null => - f.getDeclarations.headOption.map(n => ASTStringUtil.getSimpleName(n.getName)).getOrElse(f.getName) - case f: CPPFunction if f.getDefinition != null => - ASTStringUtil.getSimpleName(f.getDefinition.getName) - case other => - other.getName + case d: CPPASTIdExpression => + safeGetEvaluation(d) match { + case Some(evalBinding: EvalBinding) => + evalBinding.getBinding match { + case f: CPPFunction if f.getDeclarations != null => + f.getDeclarations.headOption.map(n => ASTStringUtil.getSimpleName(n.getName)).getOrElse(f.getName) + case f: CPPFunction if f.getDefinition != null => + ASTStringUtil.getSimpleName(f.getDefinition.getName) + case other => + other.getName + } + case _ => lastNameOfQualifiedName(ASTStringUtil.getSimpleName(d.getName)) } case d: IASTIdExpression => lastNameOfQualifiedName(ASTStringUtil.getSimpleName(d.getName)) case u: IASTUnaryExpression => shortName(u.getOperand)