Ruby: fix handling of namespaces with no 'self'

This commit is contained in:
Asger F
2022-10-31 14:00:49 +01:00
parent 9da5ec79c5
commit ab4e341e65
2 changed files with 38 additions and 3 deletions

View File

@@ -262,6 +262,9 @@ private module Cached {
)
} or
TSsaDefinitionNode(Ssa::Definition def) or
TRawNamespaceSelf(Namespace ns) {
not exists(Ssa::SelfDefinition def | def.getSourceVariable() = ns.getModuleSelfVariable())
} or
TNormalParameterNode(Parameter p) {
p instanceof SimpleParameter or
p instanceof OptionalParameter or
@@ -402,6 +405,8 @@ private module Cached {
or
// Needed for stores in type tracking
TypeTrackerSpecific::storeStepIntoSourceNode(_, n, _)
or
n instanceof TRawNamespaceSelf
}
cached
@@ -523,6 +528,38 @@ class SsaSelfDefinitionNode extends LocalSourceNode, SsaDefinitionNode {
Scope getSelfScope() { result = self.getDeclaringScope() }
}
/**
* A representative for the created or re-opened class/module in a `Namespace` that does
* not have an SSA definition for `self`.
*/
class RawNamespaceSelf extends NodeImpl, TRawNamespaceSelf {
private Namespace namespace;
RawNamespaceSelf() { this = TRawNamespaceSelf(namespace) }
/** Gets the namespace for which this represents the created or re-opened class/module. */
Namespace getNamespace() { result = namespace }
override CfgScope getCfgScope() { result = namespace.getCfgScope() }
override Location getLocationImpl() { result = namespace.getLocation() }
override string toStringImpl() { result = namespace.toString() }
}
/**
* Gets a representative for the created or re-opened class/module in a `Namespace`.
*
* This is usually the SSA definition for `self`, but if this node does not exist due to lack of liveness,
* it is the `RawNamespaceSelf` node.
*/
LocalSourceNode getNamespaceSelf(Namespace namespace) {
result.(SsaDefinitionNode).getDefinition().(Ssa::SelfDefinition).getSourceVariable() =
namespace.getModuleSelfVariable()
or
result = TRawNamespaceSelf(namespace)
}
/**
* A value returning statement, viewed as a node in a data flow graph.
*

View File

@@ -1113,9 +1113,7 @@ private LocalSourceNode getConstantAccessNode(ConstantAccess access) {
// Namespaces don't evaluate to the constant being accessed, they return the value of their last statement.
// Use the definition of 'self' in the namespace as the representative in this case.
if access instanceof Namespace
then
result.(SsaDefinitionNode).getDefinition().(Ssa::SelfDefinition).getSourceVariable() =
access.(Namespace).getModuleSelfVariable()
then result = getNamespaceSelf(access)
else result.asExpr().getExpr() = access
}