Skip to content

Commit 5891d42

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

File tree

2 files changed

+106
-66
lines changed

2 files changed

+106
-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: 104 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,89 @@ 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+
abstract int getIndirectionIndex();
1636+
}
1637+
1638+
/**
1639+
* INTERNAL: do not use.
1640+
*
1641+
* A node representing an indirection of a parameter.
1642+
*/
1643+
final class IndirectParameterNode = AbstractIndirectParameterNode;
1644+
1645+
pragma[noinline]
1646+
private predicate indirectParameterNodeHasArgumentIndexAndIndex(
1647+
IndirectInstructionParameterNode node, int argumentIndex, int indirectionIndex
1648+
) {
1649+
node.hasInstructionAndIndirectionIndex(_, indirectionIndex) and
1650+
node.getArgumentIndex() = argumentIndex
1651+
}
1652+
1653+
pragma[noinline]
1654+
private predicate indirectPositionHasArgumentIndexAndIndex(
1655+
IndirectionPosition pos, int argumentIndex, int indirectionIndex
1656+
) {
1657+
pos.getArgumentIndex() = argumentIndex and
1658+
pos.getIndirectionIndex() = indirectionIndex
1659+
}
1660+
1661+
private class IndirectInstructionParameterNode extends AbstractIndirectParameterNode instanceof IndirectInstruction
1662+
{
1663+
InitializeParameterInstruction init;
1664+
1665+
IndirectInstructionParameterNode() {
1666+
IndirectInstruction.super.hasInstructionAndIndirectionIndex(init, _)
1667+
}
1668+
1669+
int getArgumentIndex() { init.hasIndex(result) }
1670+
1671+
override Location getLocationImpl() { result = IndirectInstruction.super.getLocationImpl() }
1672+
1673+
override string toStringImpl() {
1674+
exists(string prefix | prefix = stars(this) |
1675+
result = prefix + this.getParameter().toString()
1676+
or
1677+
not exists(this.getParameter()) and
1678+
result = prefix + "this"
1679+
)
1680+
}
1681+
1682+
/** Gets the parameter whose indirection is initialized. */
1683+
override Parameter getParameter() { result = init.getParameter() }
1684+
1685+
override Declaration getEnclosingCallable() { result = this.getFunction() }
1686+
1687+
override Declaration getFunction() { result = init.getEnclosingFunction() }
1688+
1689+
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
1690+
this.getEnclosingCallable() = f.getUnderlyingCallable() and
1691+
exists(int argumentIndex, int indirectionIndex |
1692+
indirectPositionHasArgumentIndexAndIndex(pos, argumentIndex, indirectionIndex) and
1693+
indirectParameterNodeHasArgumentIndexAndIndex(this, argumentIndex, indirectionIndex)
1694+
)
1695+
}
1696+
1697+
/** Gets the underlying operand and the underlying indirection index. */
1698+
predicate hasInstructionAndIndirectionIndex(Instruction instr, int index) {
1699+
IndirectInstruction.super.hasInstructionAndIndirectionIndex(instr, index)
1700+
}
1701+
1702+
final override int getIndirectionIndex() { this.hasInstructionAndIndirectionIndex(init, result) }
1703+
}
1704+
16581705
/**
16591706
* The value of a parameter at function entry, viewed as a node in a data
16601707
* flow graph. This includes both explicit parameters such as `x` in `f(x)`
@@ -1664,42 +1711,33 @@ class IndirectExprNode extends Node instanceof IndirectExprNodeBase {
16641711
* `ExplicitParameterNode`, `ThisParameterNode`, or
16651712
* `ParameterIndirectionNode`.
16661713
*/
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-
}
1714+
final class ParameterNode = AbstractParameterNode;
16761715

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
1683-
1684-
/** Gets the `Parameter` associated with this node, if it exists. */
1685-
Parameter getParameter() { none() } // overridden by subclasses
1686-
}
1716+
abstract private class AbstractDirectParameterNode extends AbstractParameterNode { }
16871717

16881718
/** An explicit positional parameter, including `this`, but not `...`. */
1689-
class DirectParameterNode extends InstructionNode {
1690-
override InitializeParameterInstruction instr;
1719+
final class DirectParameterNode = AbstractDirectParameterNode;
1720+
1721+
abstract class InstructionDirectParameterNode extends InstructionNode, AbstractDirectParameterNode {
1722+
final override InitializeParameterInstruction instr;
16911723

16921724
/**
16931725
* INTERNAL: Do not use.
16941726
*
16951727
* Gets the `IRVariable` that this parameter references.
16961728
*/
1697-
IRVariable getIRVariable() { result = instr.getIRVariable() }
1729+
final IRVariable getIRVariable() { result = instr.getIRVariable() }
16981730
}
16991731

1732+
abstract private class AbstractExplicitParameterNode extends AbstractDirectParameterNode { }
1733+
1734+
final class ExplicitParameterNode = AbstractExplicitParameterNode;
1735+
17001736
/** An explicit positional parameter, not including `this` or `...`. */
1701-
private class ExplicitParameterNode extends ParameterNode, DirectParameterNode {
1702-
ExplicitParameterNode() { exists(instr.getParameter()) }
1737+
private class ExplicitParameterInstructionNode extends AbstractExplicitParameterNode,
1738+
InstructionDirectParameterNode
1739+
{
1740+
ExplicitParameterInstructionNode() { exists(instr.getParameter()) }
17031741

17041742
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
17051743
f.getUnderlyingCallable().(Function).getParameter(pos.(DirectPosition).getIndex()) =
@@ -1712,8 +1750,10 @@ private class ExplicitParameterNode extends ParameterNode, DirectParameterNode {
17121750
}
17131751

17141752
/** An implicit `this` parameter. */
1715-
class ThisParameterNode extends ParameterNode, DirectParameterNode {
1716-
ThisParameterNode() { instr.getIRVariable() instanceof IRThisVariable }
1753+
class ThisParameterInstructionNode extends AbstractExplicitParameterNode,
1754+
InstructionDirectParameterNode
1755+
{
1756+
ThisParameterInstructionNode() { instr.getIRVariable() instanceof IRThisVariable }
17171757

17181758
override predicate isParameterOf(DataFlowCallable f, ParameterPosition pos) {
17191759
pos.(DirectPosition).getIndex() = -1 and
@@ -1726,7 +1766,7 @@ class ThisParameterNode extends ParameterNode, DirectParameterNode {
17261766
/**
17271767
* A parameter node that is part of a summary.
17281768
*/
1729-
class SummaryParameterNode extends ParameterNode, FlowSummaryNode {
1769+
class SummaryParameterNode extends AbstractParameterNode, FlowSummaryNode {
17301770
SummaryParameterNode() {
17311771
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _)
17321772
}

0 commit comments

Comments
 (0)