@@ -61,6 +61,15 @@ private newtype TIRDataFlowNode =
6161 } or
6262 TFinalGlobalValue ( Ssa:: GlobalUse globalUse ) or
6363 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
6473 TFlowSummaryNode ( FlowSummaryImpl:: Private:: SummaryNode sn )
6574
6675/**
@@ -389,7 +398,7 @@ class Node extends TIRDataFlowNode {
389398 index = 0 and
390399 result = this .( ExplicitParameterNode ) .getParameter ( )
391400 or
392- this .( IndirectParameterNode ) .hasInstructionAndIndirectionIndex ( _ , index ) and
401+ this .( IndirectParameterNode ) .getIndirectionIndex ( ) = index and
393402 result = this .( IndirectParameterNode ) .getParameter ( )
394403 }
395404
@@ -737,6 +746,40 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
737746 override string toStringImpl ( ) { result = globalDef .toString ( ) }
738747}
739748
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+
740783/**
741784 * A data-flow node used to model flow summaries. That is, a dataflow node
742785 * that is synthesized to represent a parameter, return value, or other part
@@ -767,42 +810,6 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
767810 override string toStringImpl ( ) { result = this .getSummaryNode ( ) .toString ( ) }
768811}
769812
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-
806813/**
807814 * INTERNAL: do not use.
808815 *
@@ -1655,6 +1662,88 @@ class IndirectExprNode extends Node instanceof IndirectExprNodeBase {
16551662 }
16561663}
16571664
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+
16581747/**
16591748 * The value of a parameter at function entry, viewed as a node in a data
16601749 * flow graph. This includes both explicit parameters such as `x` in `f(x)`
@@ -1664,42 +1753,38 @@ class IndirectExprNode extends Node instanceof IndirectExprNodeBase {
16641753 * `ExplicitParameterNode`, `ThisParameterNode`, or
16651754 * `ParameterIndirectionNode`.
16661755 */
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 ;
16761757
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 { }
16871759
16881760/** 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 ;
16911770
16921771 /**
16931772 * INTERNAL: Do not use.
16941773 *
16951774 * Gets the `IRVariable` that this parameter references.
16961775 */
1697- IRVariable getIRVariable ( ) { result = instr .getIRVariable ( ) }
1776+ final IRVariable getIRVariable ( ) { result = instr .getIRVariable ( ) }
16981777}
16991778
1779+ abstract private class AbstractExplicitParameterNode extends AbstractDirectParameterNode { }
1780+
1781+ final class ExplicitParameterNode = AbstractExplicitParameterNode ;
1782+
17001783/** 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 ( ) ) }
17031788
17041789 override predicate isParameterOf ( DataFlowCallable f , ParameterPosition pos ) {
17051790 f .getUnderlyingCallable ( ) .( Function ) .getParameter ( pos .( DirectPosition ) .getIndex ( ) ) =
@@ -1712,8 +1797,10 @@ private class ExplicitParameterNode extends ParameterNode, DirectParameterNode {
17121797}
17131798
17141799/** 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 }
17171804
17181805 override predicate isParameterOf ( DataFlowCallable f , ParameterPosition pos ) {
17191806 pos .( DirectPosition ) .getIndex ( ) = - 1 and
@@ -1726,7 +1813,7 @@ class ThisParameterNode extends ParameterNode, DirectParameterNode {
17261813/**
17271814 * A parameter node that is part of a summary.
17281815 */
1729- class SummaryParameterNode extends ParameterNode , FlowSummaryNode {
1816+ class SummaryParameterNode extends AbstractParameterNode , FlowSummaryNode {
17301817 SummaryParameterNode ( ) {
17311818 FlowSummaryImpl:: Private:: summaryParameterNode ( this .getSummaryNode ( ) , _)
17321819 }
@@ -1741,31 +1828,41 @@ class SummaryParameterNode extends ParameterNode, FlowSummaryNode {
17411828 }
17421829}
17431830
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 }
17511835
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 }
17581845}
17591846
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+
17621852 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
17671858 )
17681859 }
1860+
1861+ override int getIndirectionIndex ( ) {
1862+ result = BodyLessParameterNodeImpl .super .getIndirectionIndex ( )
1863+ }
1864+
1865+ override Parameter getParameter ( ) { result = p }
17691866}
17701867
17711868/**
0 commit comments