@@ -508,11 +508,31 @@ predicate isArgumentNode(ArgumentNode arg, DataFlowCall c, ArgumentPosition pos)
508508 * on parameters are also included.
509509 */
510510abstract class ArgumentNode extends Node {
511+ /**
512+ * Holds if this argument occurs at the given position in the given call,
513+ * and this call is represented in the source code.
514+ * The instance argument is considered to have index `-1`.
515+ */
516+ predicate sourceArgumentOf ( CallInstruction call , ArgumentPosition pos ) { none ( ) }
517+
518+ /**
519+ * Holds if this argument occurs at the given position in the given call,
520+ * and this call part of a summary.
521+ * The instance argument is considered to have index `-1`.
522+ */
523+ predicate summaryArgumentOf ( FlowSummaryImpl:: Public:: SummarizedCallable call , ArgumentPosition pos ) {
524+ none ( )
525+ }
526+
511527 /**
512528 * Holds if this argument occurs at the given position in the given call.
513529 * The instance argument is considered to have index `-1`.
514530 */
515- abstract predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) ;
531+ final predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
532+ this .sourceArgumentOf ( call .asCallInstruction ( ) , pos )
533+ or
534+ this .summaryArgumentOf ( call .asSummaryCall ( ) , pos )
535+ }
516536
517537 /** Gets the call in which this node is an argument. */
518538 DataFlowCall getCall ( ) { this .argumentOf ( result , _) }
@@ -527,16 +547,16 @@ private class PrimaryArgumentNode extends ArgumentNode, OperandNode {
527547
528548 PrimaryArgumentNode ( ) { exists ( CallInstruction call | op = call .getAnArgumentOperand ( ) ) }
529549
530- override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
550+ override predicate sourceArgumentOf ( CallInstruction call , ArgumentPosition pos ) {
531551 op = call .getArgumentOperand ( pos .( DirectPosition ) .getArgumentIndex ( ) )
532552 }
533553}
534554
535555private class SideEffectArgumentNode extends ArgumentNode , SideEffectOperandNode {
536- override predicate argumentOf ( DataFlowCall dfCall , ArgumentPosition pos ) {
556+ override predicate sourceArgumentOf ( CallInstruction c , ArgumentPosition pos ) {
537557 exists ( int indirectionIndex |
538558 pos = TIndirectionPosition ( argumentIndex , pragma [ only_bind_into ] ( indirectionIndex ) ) and
539- this .getCallInstruction ( ) = dfCall . asCallInstruction ( ) and
559+ this .getCallInstruction ( ) = c and
540560 super .hasAddressOperandAndIndirectionIndex ( arg , pragma [ only_bind_into ] ( indirectionIndex ) )
541561 )
542562 }
@@ -554,8 +574,10 @@ class SummaryArgumentNode extends ArgumentNode, FlowSummaryNode {
554574 FlowSummaryImpl:: Private:: summaryArgumentNode ( call_ .getReceiver ( ) , this .getSummaryNode ( ) , pos_ )
555575 }
556576
557- override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
558- call = call_ and
577+ override predicate summaryArgumentOf (
578+ FlowSummaryImpl:: Public:: SummarizedCallable call , ArgumentPosition pos
579+ ) {
580+ call = call_ .asSummaryCall ( ) and
559581 pos = pos_
560582 }
561583}
@@ -569,8 +591,8 @@ private class FlowSummaryArgumentNode extends ArgumentNode, FlowSummaryNode {
569591 this .getSummaryNode ( ) = FlowSummaryImpl:: Private:: summaryArgumentNode ( callInstruction , rk )
570592 }
571593
572- override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
573- call . asCallInstruction ( ) = callInstruction and
594+ override predicate sourceArgumentOf ( CallInstruction call , ArgumentPosition pos ) {
595+ call = callInstruction and
574596 pos = TFlowSummaryPosition ( rk )
575597 }
576598}
@@ -593,6 +615,32 @@ abstract class Position extends TPosition {
593615
594616 /** Gets the indirection index of this position. */
595617 abstract int getIndirectionIndex ( ) ;
618+
619+ /**
620+ * Gets the parameter associated with this position, if any.
621+ *
622+ * Since a `Position` is defined by both an argument index and an
623+ * indirection multiple `Position`s can be associated with the
624+ * same `Parameter`.
625+ */
626+ Parameter getParameter ( Function f ) {
627+ result .getFunction ( ) = f and
628+ this .getArgumentIndex ( ) = result .getIndex ( )
629+ }
630+
631+ /**
632+ * Gets the argument (or qualifier) associated with this position, if any.
633+ *
634+ * Since a `Position` is defined by both an argument index and an
635+ * indirection multiple `Position`s can be associated with the
636+ * same argument/qualifier.
637+ */
638+ Expr getArgument ( Cpp:: Call call ) {
639+ result = call .getArgument ( this .getArgumentIndex ( ) )
640+ or
641+ this .getArgumentIndex ( ) = - 1 and
642+ result = call .getQualifier ( )
643+ }
596644}
597645
598646class DirectPosition extends Position , TDirectPosition {
@@ -1189,6 +1237,11 @@ class DataFlowCall extends TDataFlowCall {
11891237 */
11901238 CallInstruction asCallInstruction ( ) { none ( ) }
11911239
1240+ /**
1241+ * Gets the underlying summarized call, if any.
1242+ */
1243+ FlowSummaryImpl:: Public:: SummarizedCallable asSummaryCall ( ) { none ( ) }
1244+
11921245 /**
11931246 * Gets the operand the specifies the target function of the call.
11941247 */
@@ -1306,6 +1359,8 @@ class SummaryCall extends DataFlowCall, TSummaryCall {
13061359 */
13071360 FlowSummaryImpl:: Private:: SummaryNode getReceiver ( ) { result = receiver }
13081361
1362+ final override FlowSummaryImpl:: Public:: SummarizedCallable asSummaryCall ( ) { result = c }
1363+
13091364 // no implementation for `getCallTargetOperand()`, `getStaticCallTarget()`
13101365 // or `getArgumentOperand(int index)`. This is because the flow summary
13111366 // library is responsible for finding the call target, and there are no
0 commit comments