C#: Introduce `Ssa::Definition::getElement()` and `AssignableDefinition::getElement()`

This commit is contained in:
Tom Hvitved 2018-12-19 14:56:56 +01:00
Родитель 91e4f7ad83
Коммит 10627738d0
3 изменённых файлов: 27 добавлений и 3 удалений
csharp/ql/src/semmle/code/csharp

Просмотреть файл

@ -484,6 +484,12 @@ class AssignableDefinition extends TAssignableDefinition {
*/
Expr getExpr() { none() }
/**
* Gets the underlying element associated with this definition. This is either
* an expression or a parameter.
*/
Element getElement() { result = this.getExpr() }
/** DEPRECATED: Use `getAControlFlowNode()` instead. */
deprecated
ControlFlow::Node getControlFlowNode() { result = this.getAControlFlowNode() }
@ -800,6 +806,8 @@ module AssignableDefinitions {
result = p.getCallable().getEntryPoint()
}
override Parameter getElement() { result = p }
override Callable getEnclosingCallable() {
result = p.getCallable()
}

Просмотреть файл

@ -163,9 +163,9 @@ private predicate defMaybeNull(Ssa::Definition def, string msg, Element reason)
de = def.getARead() |
reason = de.getANullCheck(_, true) and
msg = "as suggested by $@ null check" and
not def instanceof Ssa::PseudoDefinition and
strictcount(Location l |
l = any(Ssa::Definition def0 | de = def0.getARead()).getLocation()
not de = any(Ssa::PseudoDefinition pdef).getARead() and
strictcount(Element e |
e = any(Ssa::Definition def0 | de = def0.getARead()).getElement()
) = 1 and
not nonNullDef(def) and
// Don't use a check as reason if there is a `null` assignment

Просмотреть файл

@ -2252,6 +2252,18 @@ module Ssa {
/** Gets the basic block to which this SSA definition belongs. */
BasicBlock getBasicBlock() { this.definesAt(result, _) }
/**
* Gets the syntax element associated with this SSA definition, if any.
* This is either an expression, for example `x = 0`, a parameter, or a
* callable. Pseudo nodes have no associated syntax element.
*/
Element getElement() {
exists(BasicBlock bb, int i |
this.definesAt(bb, i) |
result = bb.getNode(i).getElement()
)
}
/**
* Holds if this SSA definition assigns to `out`/`ref` parameter `p`, and the
* parameter may remain unchanged throughout the rest of the enclosing callable.
@ -2341,6 +2353,8 @@ module Ssa {
isCapturedVariableDefinitionFlowOut(this, cdef)
}
override Element getElement() { result = ad.getElement() }
override string toString() {
if this.getADefinition() instanceof AssignableDefinitions::ImplicitParameterDefinition then
result = getToStringPrefix(this) + "SSA param(" + this.getSourceVariable() + ")"
@ -2384,6 +2398,8 @@ module Ssa {
)
}
override Callable getElement() { result = this.getCallable() }
override string toString() {
if this.getSourceVariable().getAssignable() instanceof LocalScopeVariable then
result = getToStringPrefix(this) + "SSA capture def(" + this.getSourceVariable() + ")"