Skip to content

Commit

Permalink
Providing a new HasDynamicVariable language trait
Browse files Browse the repository at this point in the history
Merging the old python extra pass into the `SymbolResolver` using the trait.
  • Loading branch information
oxisto committed Feb 11, 2025
1 parent b45fb46 commit 096c652
Show file tree
Hide file tree
Showing 12 changed files with 697 additions and 576 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,20 @@ package de.fraunhofer.aisec.cpg.frontends

import de.fraunhofer.aisec.cpg.ScopeManager
import de.fraunhofer.aisec.cpg.TranslationContext
import de.fraunhofer.aisec.cpg.graph.HasOperatorCode
import de.fraunhofer.aisec.cpg.graph.HasOverloadedOperation
import de.fraunhofer.aisec.cpg.graph.LanguageProvider
import de.fraunhofer.aisec.cpg.graph.Name
import de.fraunhofer.aisec.cpg.graph.*
import de.fraunhofer.aisec.cpg.graph.declarations.Declaration
import de.fraunhofer.aisec.cpg.graph.declarations.FunctionDeclaration
import de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration
import de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration
import de.fraunhofer.aisec.cpg.graph.scopes.*
import de.fraunhofer.aisec.cpg.graph.edges.flows.*
import de.fraunhofer.aisec.cpg.graph.scopes.GlobalScope
import de.fraunhofer.aisec.cpg.graph.scopes.RecordScope
import de.fraunhofer.aisec.cpg.graph.scopes.Scope
import de.fraunhofer.aisec.cpg.graph.scopes.Symbol
import de.fraunhofer.aisec.cpg.graph.statements.expressions.*
import de.fraunhofer.aisec.cpg.passes.*
import de.fraunhofer.aisec.cpg.passes.ResolveCallExpressionAmbiguityPass
import de.fraunhofer.aisec.cpg.passes.ResolveMemberExpressionAmbiguityPass
import de.fraunhofer.aisec.cpg.passes.SymbolResolver
import kotlin.reflect.KClass

/**
Expand Down Expand Up @@ -298,6 +302,26 @@ inline infix fun <reified T : HasOverloadedOperation> KClass<T>.of(
return Pair(T::class, operatorCode)
}

/**
* A language trait that specifies that this language has dynamic declarations, meaning that
* declarations can be added to the symbol table at runtime. Since we are a static analysis tools,
* we can only deliver an approximation to the actual behaviour.
*/
interface HasDynamicDeclarations : LanguageTrait {

/**
* A callback that can be used by a language to provide a declaration for a reference. The
* language is responsible for
* - Adding the declaration to the symbol table (using [ScopeManager.addDeclaration]; as well as
* adding it to the AST
* - Injecting the declaration into the EOG path (if necessary). Since this reference might be
* part of different AST expressions different approaches might be necessary. The utility
* functions [Node.insertNodeBeforeInEOGPath] and [Node.insertNodeAfterwardInEOGPath] should
* be used.
*/
fun SymbolResolver.provideDeclaration(ref: Reference): Declaration?
}

/** Checks whether the name for a function (as [CharSequence]) is a known operator name. */
context(LanguageProvider)
val CharSequence.isKnownOperatorName: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import de.fraunhofer.aisec.cpg.graph.Node
import de.fraunhofer.aisec.cpg.graph.StatementHolder
import de.fraunhofer.aisec.cpg.graph.declarations.*
import de.fraunhofer.aisec.cpg.graph.edges.flows.EvaluationOrder
import de.fraunhofer.aisec.cpg.graph.edges.flows.insertNodeBeforeInEOGPath
import de.fraunhofer.aisec.cpg.graph.firstParentOrNull
import de.fraunhofer.aisec.cpg.graph.statements.*
import de.fraunhofer.aisec.cpg.graph.statements.expressions.*
Expand Down Expand Up @@ -1482,3 +1483,28 @@ open class EvaluationOrderGraphPass(ctx: TranslationContext) : TranslationUnitPa
nextEdgeBranch = tmpBranchLabel
}
}

/**
* This adds an extra declaration (see [AssignExpression.declarations] to the EOG of the
* [AssignExpression]. This is needed if we somehow add the declaration after the pass has initially
* run.
*
* This mimics the behaviour in [EvaluationOrderGraphPass.handleAssignExpression].
*/
fun AssignExpression.addDeclarationToEOG(decl: Declaration): Boolean? {
// We need to insert the declaration before the first lhs ref
return this.lhs.firstOrNull()?.insertNodeBeforeInEOGPath(decl)
}

/**
* This adds an extra local declaration (see [ForEachStatement.locals]) to the EOG of the
* [ForEachStatement]. This is needed if we somehow add the declaration after the pass has initially
* run.
*
* This mimics the behaviour in [EvaluationOrderGraphPass.handleForEachStatement].
*/
fun ForEachStatement.addDeclarationToEOG(decl: Declaration): Boolean? {
// Actually, it seems like we are not adding the declaration of a local variable to the EOG of
// the ForEachStatement at all.
return true
}
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ open class SymbolResolver(ctx: TranslationContext) : ComponentPass(ctx) {
val language = ref.language
val helperType = ref.resolutionHelper?.type

// Before we resolve anything, we give languages with dynamic declarations a chance to
// declare any variables they need. This is most likely only needed for WRITE references,
// but we let the language decide that
if (language is HasDynamicDeclarations) {
with(language) { provideDeclaration(ref) }
}

// Ignore references to anonymous identifiers, if the language supports it (e.g., the _
// identifier in Go)
if (
Expand Down Expand Up @@ -312,6 +319,13 @@ open class SymbolResolver(ctx: TranslationContext) : ComponentPass(ctx) {
val base = current.base
val language = current.language

// Before we resolve anything, we give languages with dynamic declarations a chance to
// declare any variables they need. This is most likely only needed for WRITE references,
// but we let the language decide that
if (language is HasDynamicDeclarations) {
with(language) { provideDeclaration(current) }
}

// We need to adjust certain types of the base in case of a "super" expression, and we
// delegate this to the language. If that is successful, we can continue with regular
// resolving.
Expand Down
Loading

0 comments on commit 096c652

Please sign in to comment.