Skip to content

Commit

Permalink
c2cpg: fixed macro call generation with duplicated method definitions (
Browse files Browse the repository at this point in the history
…#3116)

If a macro in a header file contains a method definition already seen in some
source file we skipped that during the previous AST creation returning an empty Ast.
That crashed the macro call generation.
  • Loading branch information
max-leuthaeuser authored Jul 14, 2023
1 parent b21f3e0 commit f9a1033
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import io.joern.x2cpg.utils.NodeBuilders.newDependencyNode
import io.shiftleft.codepropertygraph.generated.EdgeTypes
import io.shiftleft.utils.IOUtils
import org.apache.commons.lang.StringUtils
import org.eclipse.cdt.core.dom.ast._
import org.eclipse.cdt.core.dom.ast.*
import org.eclipse.cdt.core.dom.ast.c.{ICASTArrayDesignator, ICASTDesignatedInitializer, ICASTFieldDesignator}
import org.eclipse.cdt.core.dom.ast.cpp._
import org.eclipse.cdt.core.dom.ast.c.ICASTTypedefNameSpecifier
import org.eclipse.cdt.core.dom.ast.cpp.*
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator
import org.eclipse.cdt.internal.core.dom.parser.c.CASTArrayRangeDesignator
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding
Expand Down Expand Up @@ -382,6 +383,7 @@ trait AstCreatorHelper { this: AstCreator =>
case e: IASTEnumerationSpecifier => ASTStringUtil.getSimpleName(e.getName)
case c: IASTCompositeTypeSpecifier => ASTStringUtil.getSimpleName(c.getName)
case e: IASTElaboratedTypeSpecifier => ASTStringUtil.getSimpleName(e.getName)
case s: IASTNamedTypeSpecifier => ASTStringUtil.getSimpleName(s.getName)
case other => notHandledYet(other); ""
}
name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ trait MacroHandler { this: AstCreator =>
* invocation and attach `ast` as its child.
*/
def asChildOfMacroCall(node: IASTNode, ast: Ast): Ast = {
// If a macro in a header file contained a method definition already seen in some
// source file we skipped that during the previous AST creation and returned an empty AST.
if (ast.root.isEmpty && isExpandedFromMacro(node)) return ast
// We do nothing for locals only.
if (ast.nodes.size == 1 && ast.root.exists(_.isInstanceOf[NewLocal])) return ast
// Otherwise, we create the synthetic call AST.
val matchingMacro = extractMatchingMacro(node)
val macroCallAst = matchingMacro.map { case (mac, args) => createMacroCallAst(ast, node, mac, args) }
macroCallAst match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ import io.shiftleft.semanticcpg.language._
class TypeNodePassTests extends CCodeToCpgSuite {

"TypeNodePass" should {

"be correct for top level type definitions" in {
val cpg = code("""
|typedef const char * foo;
|typedef foo * bar;
|""".stripMargin)
val List(foo) = cpg.typeDecl.nameExact("foo").l
val List(bar) = cpg.typeDecl.nameExact("bar").l
foo.aliasTypeFullName shouldBe Some("char")
bar.aliasTypeFullName shouldBe Some("char")
}

"be correct for static decl assignment" in {
val cpg = code("""
|void method() {
Expand Down

0 comments on commit f9a1033

Please sign in to comment.