Skip to content

Commit 111ad8b

Browse files
committed
C++: Refactor parameter nodes into an abstract class that's easier to extend.
1 parent 43df0cd commit 111ad8b

File tree

2 files changed

+110
-66
lines changed

2 files changed

+110
-66
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,7 +1247,7 @@ module IsUnreachableInCall {
12471247

12481248
predicate isUnreachableInCall(Node n, DataFlowCall call) {
12491249
exists(
1250-
DirectParameterNode paramNode, ConstantIntegralTypeArgumentNode arg,
1250+
InstructionDirectParameterNode paramNode, ConstantIntegralTypeArgumentNode arg,
12511251
IntegerConstantInstruction constant, int k, Operand left, Operand right, IRBlock block
12521252
|
12531253
// arg flows into `paramNode`
@@ -1461,7 +1461,7 @@ private predicate getAdditionalFlowIntoCallNodeTermStep(Node node1, Node node2)
14611461
/** Gets the `IRVariable` associated with the parameter node `p`. */
14621462
pragma[nomagic]
14631463
private IRVariable getIRVariableForParameterNode(ParameterNode p) {
1464-
result = p.(DirectParameterNode).getIRVariable()
1464+
result = p.(InstructionDirectParameterNode).getIRVariable()
14651465
or
14661466
result.getAst() = p.(IndirectParameterNode).getParameter()
14671467
}

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 108 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ class Node extends TIRDataFlowNode {
389389
index = 0 and
390390
result = this.(ExplicitParameterNode).getParameter()
391391
or
392-
this.(IndirectParameterNode).hasInstructionAndIndirectionIndex(_, index) and
392+
this.(IndirectParameterNode).getIndirectionIndex() = index and
393393
result = this.(IndirectParameterNode).getParameter()
394394
}
395395

@@ -767,42 +767,6 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
767767
override string toStringImpl() { result = this.getSummaryNode().toString() }
768768
}
769769

770-
/**
771-
* INTERNAL: do not use.
772-
*
773-
* A node representing an indirection of a parameter.
774-
*/
775-
class IndirectParameterNode extends Node instanceof IndirectInstruction {
776-
InitializeParameterInstruction init;
777-
778-
IndirectParameterNode() { IndirectInstruction.super.hasInstructionAndIndirectionIndex(init, _) }
779-
780-
int getArgumentIndex() { init.hasIndex(result) }
781-
782-
/** Gets the parameter whose indirection is initialized. */
783-
Parameter getParameter() { result = init.getParameter() }
784-
785-
override Declaration getEnclosingCallable() { result = this.getFunction() }
786-
787-
override Declaration getFunction() { result = init.getEnclosingFunction() }
788-
789-
/** Gets the underlying operand and the underlying indirection index. */
790-
predicate hasInstructionAndIndirectionIndex(Instruction instr, int index) {
791-
IndirectInstruction.super.hasInstructionAndIndirectionIndex(instr, index)
792-
}
793-
794-
override Location getLocationImpl() { result = this.getParameter().getLocation() }
795-
796-
override string toStringImpl() {
797-
exists(string prefix | prefix = stars(this) |
798-
result = prefix + this.getParameter().toString()
799-
or
800-
not exists(this.getParameter()) and
801-
result = prefix + "this"
802-
)
803-
}
804-
}
805-
806770
/**
807771
* INTERNAL: do not use.
808772
*
@@ -1655,6 +1619,88 @@ class IndirectExprNode extends Node instanceof IndirectExprNodeBase {
16551619
}
16561620
}
16571621

1622+
abstract private class AbstractParameterNode extends Node {
1623+
/**
1624+
* Holds if this node is the parameter of `f` at the specified position. The
1625+
* implicit `this` parameter is considered to have position `-1`, and
1626+
* pointer-indirection parameters are at further negative positions.
1627+
*/
1628+
abstract predicate isParameterOf(DataFlowCallable f, ParameterPosition pos);
1629+
1630+
/** Gets the `Parameter` associated with this node, if it exists. */
1631+
Parameter getParameter() { none() } // overridden by subclasses
1632+
}
1633+
1634+
abstract private class AbstractIndirectParameterNode extends AbstractParameterNode {
1635+
/** Gets the indirection index of this parameter node. */
1636+
abstract int getIndirectionIndex();
1637+
}
1638+
1639+
/**
1640+
* INTERNAL: do not use.
1641+
*
1642+
* A node representing an indirection of a parameter.
1643+
*/
1644+
final class IndirectParameterNode = AbstractIndirectParameterNode;
1645+
1646+
pragma[noinline]
1647+
private predicate indirectParameterNodeHasArgumentIndexAndIndex(
1648+
IndirectInstructionParameterNode node, int argumentIndex, int indirectionIndex
1649+
) {
1650+
node.hasInstructionAndIndirectionIndex(_, indirectionIndex) and
1651+
node.getArgumentIndex() = argumentIndex
1652+
}
1653+
1654+
pragma[noinline]
1655+
private predicate indirectPositionHasArgumentIndexAndIndex(
1656+
IndirectionPosition pos, int argumentIndex, int indirectionIndex
1657+
) {
1658+
pos.getArgumentIndex() = argumentIndex and
1659+
pos.getIndirectionIndex() = indirectionIndex
1660+
}
1661+
1662+
private class IndirectInstructionParameterNode extends AbstractIndirectParameterNode instanceof IndirectInstruction
1663+
{
1664+
InitializeParameterInstruction init;
1665+
1666+
IndirectInstructionParameterNode() {
1667+
IndirectInstruction.super.hasInstructionAndIndirectionIndex(init, _)
1668+
}
1669+
1670+
int getArgumentIndex() { init.hasIndex(result) }
1671+
1672+
override string toStringImpl() {
1673+
exists(string prefix | prefix = stars(this) |
1674+
result = prefix + this.getParameter().toString()
1675+
or
1676+
not exists(this.getParameter()) and
1677+
result = prefix + "this"
1678+
)
1679+
}
1680+
1681+
/** Gets the parameter whose indirection is initialized. */
1682+
override Parameter getParameter() { result = init.getParameter() }
1683+
1684+
override Declaration getEnclosingCallable() { result = this.getFunction() }
1685+
1686+
override Declaration getFunction() { result = init.getEnclosingFunction() }
1687+
1688+
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
1689+
this.getEnclosingCallable() = f.getUnderlyingCallable() and
1690+
exists(int argumentIndex, int indirectionIndex |
1691+
indirectPositionHasArgumentIndexAndIndex(pos, argumentIndex, indirectionIndex) and
1692+
indirectParameterNodeHasArgumentIndexAndIndex(this, argumentIndex, indirectionIndex)
1693+
)
1694+
}
1695+
1696+
/** Gets the underlying operand and the underlying indirection index. */
1697+
predicate hasInstructionAndIndirectionIndex(Instruction instr, int index) {
1698+
IndirectInstruction.super.hasInstructionAndIndirectionIndex(instr, index)
1699+
}
1700+
1701+
final override int getIndirectionIndex() { this.hasInstructionAndIndirectionIndex(init, result) }
1702+
}
1703+
16581704
/**
16591705
* The value of a parameter at function entry, viewed as a node in a data
16601706
* flow graph. This includes both explicit parameters such as `x` in `f(x)`
@@ -1664,42 +1710,38 @@ class IndirectExprNode extends Node instanceof IndirectExprNodeBase {
16641710
* `ExplicitParameterNode`, `ThisParameterNode`, or
16651711
* `ParameterIndirectionNode`.
16661712
*/
1667-
class ParameterNode extends Node {
1668-
ParameterNode() {
1669-
// To avoid making this class abstract, we enumerate its values here
1670-
this.asInstruction() instanceof InitializeParameterInstruction
1671-
or
1672-
this instanceof IndirectParameterNode
1673-
or
1674-
FlowSummaryImpl::Private::summaryParameterNode(this.(FlowSummaryNode).getSummaryNode(), _)
1675-
}
1676-
1677-
/**
1678-
* Holds if this node is the parameter of `f` at the specified position. The
1679-
* implicit `this` parameter is considered to have position `-1`, and
1680-
* pointer-indirection parameters are at further negative positions.
1681-
*/
1682-
predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) { none() } // overridden by subclasses
1713+
final class ParameterNode = AbstractParameterNode;
16831714

1684-
/** Gets the `Parameter` associated with this node, if it exists. */
1685-
Parameter getParameter() { none() } // overridden by subclasses
1686-
}
1715+
abstract private class AbstractDirectParameterNode extends AbstractParameterNode { }
16871716

16881717
/** An explicit positional parameter, including `this`, but not `...`. */
1689-
class DirectParameterNode extends InstructionNode {
1690-
override InitializeParameterInstruction instr;
1718+
final class DirectParameterNode = AbstractDirectParameterNode;
1719+
1720+
/**
1721+
* INTERNAL: Do not use.
1722+
*
1723+
* A non-indirect parameter node that is represented as an `Instruction`.
1724+
*/
1725+
abstract class InstructionDirectParameterNode extends InstructionNode, AbstractDirectParameterNode {
1726+
final override InitializeParameterInstruction instr;
16911727

16921728
/**
16931729
* INTERNAL: Do not use.
16941730
*
16951731
* Gets the `IRVariable` that this parameter references.
16961732
*/
1697-
IRVariable getIRVariable() { result = instr.getIRVariable() }
1733+
final IRVariable getIRVariable() { result = instr.getIRVariable() }
16981734
}
16991735

1736+
abstract private class AbstractExplicitParameterNode extends AbstractDirectParameterNode { }
1737+
1738+
final class ExplicitParameterNode = AbstractExplicitParameterNode;
1739+
17001740
/** An explicit positional parameter, not including `this` or `...`. */
1701-
private class ExplicitParameterNode extends ParameterNode, DirectParameterNode {
1702-
ExplicitParameterNode() { exists(instr.getParameter()) }
1741+
private class ExplicitParameterInstructionNode extends AbstractExplicitParameterNode,
1742+
InstructionDirectParameterNode
1743+
{
1744+
ExplicitParameterInstructionNode() { exists(instr.getParameter()) }
17031745

17041746
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
17051747
f.getUnderlyingCallable().(Function).getParameter(pos.(DirectPosition).getIndex()) =
@@ -1712,8 +1754,10 @@ private class ExplicitParameterNode extends ParameterNode, DirectParameterNode {
17121754
}
17131755

17141756
/** An implicit `this` parameter. */
1715-
class ThisParameterNode extends ParameterNode, DirectParameterNode {
1716-
ThisParameterNode() { instr.getIRVariable() instanceof IRThisVariable }
1757+
class ThisParameterInstructionNode extends AbstractExplicitParameterNode,
1758+
InstructionDirectParameterNode
1759+
{
1760+
ThisParameterInstructionNode() { instr.getIRVariable() instanceof IRThisVariable }
17171761

17181762
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
17191763
pos.(DirectPosition).getIndex() = -1 and
@@ -1726,7 +1770,7 @@ class ThisParameterNode extends ParameterNode, DirectParameterNode {
17261770
/**
17271771
* A parameter node that is part of a summary.
17281772
*/
1729-
class SummaryParameterNode extends ParameterNode, FlowSummaryNode {
1773+
class SummaryParameterNode extends AbstractParameterNode, FlowSummaryNode {
17301774
SummaryParameterNode() {
17311775
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _)
17321776
}

0 commit comments

Comments
 (0)