@@ -61,6 +61,15 @@ private newtype TIRDataFlowNode =
61
61
} or
62
62
TFinalGlobalValue ( Ssa:: GlobalUse globalUse ) or
63
63
TInitialGlobalValue ( Ssa:: GlobalDef globalUse ) or
64
+ TBodyLessParameterNodeImpl ( Parameter p , int indirectionIndex ) {
65
+ // Rule out parameters of catch blocks.
66
+ not exists ( p .getCatchBlock ( ) ) and
67
+ // We subtract one because `getMaxIndirectionsForType` returns the maximum
68
+ // indirection for a glvalue of a given type, and this doesn't apply to
69
+ // parameters.
70
+ indirectionIndex = [ 0 .. Ssa:: getMaxIndirectionsForType ( p .getUnspecifiedType ( ) ) - 1 ] and
71
+ not any ( InitializeParameterInstruction init ) .getParameter ( ) = p
72
+ } or
64
73
TFlowSummaryNode ( FlowSummaryImpl:: Private:: SummaryNode sn )
65
74
66
75
/**
@@ -389,7 +398,7 @@ class Node extends TIRDataFlowNode {
389
398
index = 0 and
390
399
result = this .( ExplicitParameterNode ) .getParameter ( )
391
400
or
392
- this .( IndirectParameterNode ) .hasInstructionAndIndirectionIndex ( _ , index ) and
401
+ this .( IndirectParameterNode ) .getIndirectionIndex ( ) = index and
393
402
result = this .( IndirectParameterNode ) .getParameter ( )
394
403
}
395
404
@@ -737,6 +746,40 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
737
746
override string toStringImpl ( ) { result = globalDef .toString ( ) }
738
747
}
739
748
749
+ /**
750
+ * INTERNAL: do not use.
751
+ *
752
+ * A node representing a parameter for a function with no body.
753
+ */
754
+ class BodyLessParameterNodeImpl extends Node , TBodyLessParameterNodeImpl {
755
+ Parameter p ;
756
+ int indirectionIndex ;
757
+
758
+ BodyLessParameterNodeImpl ( ) { this = TBodyLessParameterNodeImpl ( p , indirectionIndex ) }
759
+
760
+ override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
761
+
762
+ override Declaration getFunction ( ) { result = p .getFunction ( ) }
763
+
764
+ /** Gets the indirection index of this node. */
765
+ int getIndirectionIndex ( ) { result = indirectionIndex }
766
+
767
+ override DataFlowType getType ( ) {
768
+ result = getTypeImpl ( p .getUnderlyingType ( ) , this .getIndirectionIndex ( ) )
769
+ }
770
+
771
+ final override Location getLocationImpl ( ) {
772
+ result = unique( | | p .getLocation ( ) )
773
+ or
774
+ count ( p .getLocation ( ) ) != 1 and
775
+ result instanceof UnknownDefaultLocation
776
+ }
777
+
778
+ final override string toStringImpl ( ) {
779
+ exists ( string prefix | prefix = stars ( this ) | result = prefix + p .toString ( ) )
780
+ }
781
+ }
782
+
740
783
/**
741
784
* A data-flow node used to model flow summaries. That is, a dataflow node
742
785
* that is synthesized to represent a parameter, return value, or other part
@@ -767,42 +810,6 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
767
810
override string toStringImpl ( ) { result = this .getSummaryNode ( ) .toString ( ) }
768
811
}
769
812
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
-
806
813
/**
807
814
* INTERNAL: do not use.
808
815
*
@@ -1655,6 +1662,88 @@ class IndirectExprNode extends Node instanceof IndirectExprNodeBase {
1655
1662
}
1656
1663
}
1657
1664
1665
+ abstract private class AbstractParameterNode extends Node {
1666
+ /**
1667
+ * Holds if this node is the parameter of `f` at the specified position. The
1668
+ * implicit `this` parameter is considered to have position `-1`, and
1669
+ * pointer-indirection parameters are at further negative positions.
1670
+ */
1671
+ abstract predicate isParameterOf ( DataFlowCallable f , ParameterPosition pos ) ;
1672
+
1673
+ /** Gets the `Parameter` associated with this node, if it exists. */
1674
+ Parameter getParameter ( ) { none ( ) } // overridden by subclasses
1675
+ }
1676
+
1677
+ abstract private class AbstractIndirectParameterNode extends AbstractParameterNode {
1678
+ /** Gets the indirection index of this parameter node. */
1679
+ abstract int getIndirectionIndex ( ) ;
1680
+ }
1681
+
1682
+ /**
1683
+ * INTERNAL: do not use.
1684
+ *
1685
+ * A node representing an indirection of a parameter.
1686
+ */
1687
+ final class IndirectParameterNode = AbstractIndirectParameterNode ;
1688
+
1689
+ pragma [ noinline]
1690
+ private predicate indirectParameterNodeHasArgumentIndexAndIndex (
1691
+ IndirectInstructionParameterNode node , int argumentIndex , int indirectionIndex
1692
+ ) {
1693
+ node .hasInstructionAndIndirectionIndex ( _, indirectionIndex ) and
1694
+ node .getArgumentIndex ( ) = argumentIndex
1695
+ }
1696
+
1697
+ pragma [ noinline]
1698
+ private predicate indirectPositionHasArgumentIndexAndIndex (
1699
+ IndirectionPosition pos , int argumentIndex , int indirectionIndex
1700
+ ) {
1701
+ pos .getArgumentIndex ( ) = argumentIndex and
1702
+ pos .getIndirectionIndex ( ) = indirectionIndex
1703
+ }
1704
+
1705
+ private class IndirectInstructionParameterNode extends AbstractIndirectParameterNode instanceof IndirectInstruction
1706
+ {
1707
+ InitializeParameterInstruction init ;
1708
+
1709
+ IndirectInstructionParameterNode ( ) {
1710
+ IndirectInstruction .super .hasInstructionAndIndirectionIndex ( init , _)
1711
+ }
1712
+
1713
+ int getArgumentIndex ( ) { init .hasIndex ( result ) }
1714
+
1715
+ override string toStringImpl ( ) {
1716
+ exists ( string prefix | prefix = stars ( this ) |
1717
+ result = prefix + this .getParameter ( ) .toString ( )
1718
+ or
1719
+ not exists ( this .getParameter ( ) ) and
1720
+ result = prefix + "this"
1721
+ )
1722
+ }
1723
+
1724
+ /** Gets the parameter whose indirection is initialized. */
1725
+ override Parameter getParameter ( ) { result = init .getParameter ( ) }
1726
+
1727
+ override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
1728
+
1729
+ override Declaration getFunction ( ) { result = init .getEnclosingFunction ( ) }
1730
+
1731
+ override predicate isParameterOf ( DataFlowCallable f , ParameterPosition pos ) {
1732
+ this .getEnclosingCallable ( ) = f .getUnderlyingCallable ( ) and
1733
+ exists ( int argumentIndex , int indirectionIndex |
1734
+ indirectPositionHasArgumentIndexAndIndex ( pos , argumentIndex , indirectionIndex ) and
1735
+ indirectParameterNodeHasArgumentIndexAndIndex ( this , argumentIndex , indirectionIndex )
1736
+ )
1737
+ }
1738
+
1739
+ /** Gets the underlying operand and the underlying indirection index. */
1740
+ predicate hasInstructionAndIndirectionIndex ( Instruction instr , int index ) {
1741
+ IndirectInstruction .super .hasInstructionAndIndirectionIndex ( instr , index )
1742
+ }
1743
+
1744
+ final override int getIndirectionIndex ( ) { this .hasInstructionAndIndirectionIndex ( init , result ) }
1745
+ }
1746
+
1658
1747
/**
1659
1748
* The value of a parameter at function entry, viewed as a node in a data
1660
1749
* flow graph. This includes both explicit parameters such as `x` in `f(x)`
@@ -1664,42 +1753,38 @@ class IndirectExprNode extends Node instanceof IndirectExprNodeBase {
1664
1753
* `ExplicitParameterNode`, `ThisParameterNode`, or
1665
1754
* `ParameterIndirectionNode`.
1666
1755
*/
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
- }
1756
+ final class ParameterNode = AbstractParameterNode ;
1676
1757
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
- }
1758
+ abstract private class AbstractDirectParameterNode extends AbstractParameterNode { }
1687
1759
1688
1760
/** An explicit positional parameter, including `this`, but not `...`. */
1689
- class DirectParameterNode extends InstructionNode {
1690
- override InitializeParameterInstruction instr ;
1761
+ final class DirectParameterNode = AbstractDirectParameterNode ;
1762
+
1763
+ /**
1764
+ * INTERNAL: Do not use.
1765
+ *
1766
+ * A non-indirect parameter node that is represented as an `Instruction`.
1767
+ */
1768
+ abstract class InstructionDirectParameterNode extends InstructionNode , AbstractDirectParameterNode {
1769
+ final override InitializeParameterInstruction instr ;
1691
1770
1692
1771
/**
1693
1772
* INTERNAL: Do not use.
1694
1773
*
1695
1774
* Gets the `IRVariable` that this parameter references.
1696
1775
*/
1697
- IRVariable getIRVariable ( ) { result = instr .getIRVariable ( ) }
1776
+ final IRVariable getIRVariable ( ) { result = instr .getIRVariable ( ) }
1698
1777
}
1699
1778
1779
+ abstract private class AbstractExplicitParameterNode extends AbstractDirectParameterNode { }
1780
+
1781
+ final class ExplicitParameterNode = AbstractExplicitParameterNode ;
1782
+
1700
1783
/** An explicit positional parameter, not including `this` or `...`. */
1701
- private class ExplicitParameterNode extends ParameterNode , DirectParameterNode {
1702
- ExplicitParameterNode ( ) { exists ( instr .getParameter ( ) ) }
1784
+ private class ExplicitParameterInstructionNode extends AbstractExplicitParameterNode ,
1785
+ InstructionDirectParameterNode
1786
+ {
1787
+ ExplicitParameterInstructionNode ( ) { exists ( instr .getParameter ( ) ) }
1703
1788
1704
1789
override predicate isParameterOf ( DataFlowCallable f , ParameterPosition pos ) {
1705
1790
f .getUnderlyingCallable ( ) .( Function ) .getParameter ( pos .( DirectPosition ) .getIndex ( ) ) =
@@ -1712,8 +1797,10 @@ private class ExplicitParameterNode extends ParameterNode, DirectParameterNode {
1712
1797
}
1713
1798
1714
1799
/** An implicit `this` parameter. */
1715
- class ThisParameterNode extends ParameterNode , DirectParameterNode {
1716
- ThisParameterNode ( ) { instr .getIRVariable ( ) instanceof IRThisVariable }
1800
+ class ThisParameterInstructionNode extends AbstractExplicitParameterNode ,
1801
+ InstructionDirectParameterNode
1802
+ {
1803
+ ThisParameterInstructionNode ( ) { instr .getIRVariable ( ) instanceof IRThisVariable }
1717
1804
1718
1805
override predicate isParameterOf ( DataFlowCallable f , ParameterPosition pos ) {
1719
1806
pos .( DirectPosition ) .getIndex ( ) = - 1 and
@@ -1726,7 +1813,7 @@ class ThisParameterNode extends ParameterNode, DirectParameterNode {
1726
1813
/**
1727
1814
* A parameter node that is part of a summary.
1728
1815
*/
1729
- class SummaryParameterNode extends ParameterNode , FlowSummaryNode {
1816
+ class SummaryParameterNode extends AbstractParameterNode , FlowSummaryNode {
1730
1817
SummaryParameterNode ( ) {
1731
1818
FlowSummaryImpl:: Private:: summaryParameterNode ( this .getSummaryNode ( ) , _)
1732
1819
}
@@ -1741,31 +1828,41 @@ class SummaryParameterNode extends ParameterNode, FlowSummaryNode {
1741
1828
}
1742
1829
}
1743
1830
1744
- pragma [ noinline]
1745
- private predicate indirectPositionHasArgumentIndexAndIndex (
1746
- IndirectionPosition pos , int argumentIndex , int indirectionIndex
1747
- ) {
1748
- pos .getArgumentIndex ( ) = argumentIndex and
1749
- pos .getIndirectionIndex ( ) = indirectionIndex
1750
- }
1831
+ private class DirectBodyLessParameterNode extends AbstractExplicitParameterNode ,
1832
+ BodyLessParameterNodeImpl
1833
+ {
1834
+ DirectBodyLessParameterNode ( ) { indirectionIndex = 0 }
1751
1835
1752
- pragma [ noinline]
1753
- private predicate indirectParameterNodeHasArgumentIndexAndIndex (
1754
- IndirectParameterNode node , int argumentIndex , int indirectionIndex
1755
- ) {
1756
- node .hasInstructionAndIndirectionIndex ( _, indirectionIndex ) and
1757
- node .getArgumentIndex ( ) = argumentIndex
1836
+ override predicate isParameterOf ( DataFlowCallable f , ParameterPosition pos ) {
1837
+ exists ( Function func |
1838
+ this .getFunction ( ) = func and
1839
+ f .asSourceCallable ( ) = func and
1840
+ func .getParameter ( pos .( DirectPosition ) .getIndex ( ) ) = p
1841
+ )
1842
+ }
1843
+
1844
+ override Parameter getParameter ( ) { result = p }
1758
1845
}
1759
1846
1760
- /** A synthetic parameter to model the pointed-to object of a pointer parameter. */
1761
- class ParameterIndirectionNode extends ParameterNode instanceof IndirectParameterNode {
1847
+ private class IndirectBodyLessParameterNode extends AbstractIndirectParameterNode ,
1848
+ BodyLessParameterNodeImpl
1849
+ {
1850
+ IndirectBodyLessParameterNode ( ) { not this instanceof DirectBodyLessParameterNode }
1851
+
1762
1852
override predicate isParameterOf ( DataFlowCallable f , ParameterPosition pos ) {
1763
- IndirectParameterNode .super .getEnclosingCallable ( ) = f .getUnderlyingCallable ( ) and
1764
- exists ( int argumentIndex , int indirectionIndex |
1765
- indirectPositionHasArgumentIndexAndIndex ( pos , argumentIndex , indirectionIndex ) and
1766
- indirectParameterNodeHasArgumentIndexAndIndex ( this , argumentIndex , indirectionIndex )
1853
+ exists ( Function func , int argumentPosition |
1854
+ this .getFunction ( ) = func and
1855
+ f .asSourceCallable ( ) = func and
1856
+ indirectPositionHasArgumentIndexAndIndex ( pos , argumentPosition , indirectionIndex ) and
1857
+ func .getParameter ( argumentPosition ) = p
1767
1858
)
1768
1859
}
1860
+
1861
+ override int getIndirectionIndex ( ) {
1862
+ result = BodyLessParameterNodeImpl .super .getIndirectionIndex ( )
1863
+ }
1864
+
1865
+ override Parameter getParameter ( ) { result = p }
1769
1866
}
1770
1867
1771
1868
/**
0 commit comments