@@ -3,6 +3,7 @@ private import DataFlowUtil
33private import semmle.code.cpp.ir.IR
44private import DataFlowDispatch
55private import semmle.code.cpp.ir.internal.IRCppLanguage
6+ private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
67private import SsaInternals as Ssa
78private import DataFlowImplCommon as DataFlowImplCommon
89private import codeql.util.Unit
@@ -381,12 +382,26 @@ private class SideEffectArgumentNode extends ArgumentNode, SideEffectOperandNode
381382 override predicate argumentOf ( DataFlowCall dfCall , ArgumentPosition pos ) {
382383 exists ( int indirectionIndex |
383384 pos = TIndirectionPosition ( argumentIndex , pragma [ only_bind_into ] ( indirectionIndex ) ) and
384- this .getCallInstruction ( ) = dfCall and
385+ this .getCallInstruction ( ) = dfCall . asCallInstruction ( ) and // TODO: or summarized call?
385386 super .hasAddressOperandAndIndirectionIndex ( _, pragma [ only_bind_into ] ( indirectionIndex ) )
386387 )
387388 }
388389}
389390
391+ class SummaryArgumentNode extends ArgumentNode , FlowSummaryNode {
392+ private SummaryCall call_ ;
393+ private ArgumentPosition pos_ ;
394+
395+ SummaryArgumentNode ( ) {
396+ FlowSummaryImpl:: Private:: summaryArgumentNode ( call_ .getReceiver ( ) , this .getSummaryNode ( ) , pos_ )
397+ }
398+
399+ override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
400+ call = call_ and
401+ pos = pos_
402+ }
403+ }
404+
390405/** A parameter position represented by an integer. */
391406class ParameterPosition = Position ;
392407
@@ -659,19 +674,19 @@ private class DirectCallOutNode extends OutNode {
659674
660675 DirectCallOutNode ( ) { simpleOutNode ( this , call ) }
661676
662- override DataFlowCall getCall ( ) { result = call }
677+ override DataFlowCall getCall ( ) { result . asCallInstruction ( ) = call } // TODO: or summarized call?
663678
664679 override ReturnKind getReturnKind ( ) { result = TNormalReturnKind ( 0 ) }
665680}
666681
667682private class IndirectCallOutNode extends OutNode , IndirectReturnOutNode {
668- override DataFlowCall getCall ( ) { result = this .getCallInstruction ( ) }
683+ override DataFlowCall getCall ( ) { result . asCallInstruction ( ) = this .getCallInstruction ( ) } // TODO: or summarized call?
669684
670685 override ReturnKind getReturnKind ( ) { result = TNormalReturnKind ( this .getIndirectionIndex ( ) ) }
671686}
672687
673688private class SideEffectOutNode extends OutNode , IndirectArgumentOutNode {
674- override DataFlowCall getCall ( ) { result = this .getCallInstruction ( ) }
689+ override DataFlowCall getCall ( ) { result . asCallInstruction ( ) = this .getCallInstruction ( ) } // TODO: or summarized call?
675690
676691 override ReturnKind getReturnKind ( ) {
677692 result = TIndirectReturnKind ( this .getArgumentIndex ( ) , this .getIndirectionIndex ( ) )
@@ -938,9 +953,111 @@ class DataFlowExpr = Expr;
938953
939954class DataFlowType = Type ;
940955
941- /** A function call relevant for data flow. */
942- class DataFlowCall extends CallInstruction {
943- DataFlowCallable getEnclosingCallable ( ) { result = this .getEnclosingFunction ( ) }
956+ cached
957+ newtype TDataFlowCall =
958+ TNormalCall ( CallInstruction call ) or
959+ TSummaryCall (
960+ FlowSummaryImpl:: Public:: SummarizedCallable c , FlowSummaryImpl:: Private:: SummaryNode receiver
961+ ) {
962+ FlowSummaryImpl:: Private:: summaryCallbackRange ( c , receiver )
963+ }
964+
965+ /**
966+ * A function call relevant for data flow. This includes calls from source
967+ * code and calls inside library callables with a flow summary.
968+ */
969+ class DataFlowCall extends TDataFlowCall {
970+ /**
971+ * Gets the underlying data flow call instruction, if any.
972+ */
973+ CallInstruction asCallInstruction ( ) { none ( ) }
974+
975+ /**
976+ * Gets the operand the specifies the target function of the call.
977+ */
978+ CallTargetOperand getCallTargetOperand ( ) { none ( ) }
979+
980+ /**
981+ * Gets the `Function` that the call targets, if this is statically known.
982+ */
983+ Function getStaticCallTarget ( ) { none ( ) }
984+
985+ /**
986+ * Gets the `index`'th argument operand. The qualifier is considered to have index `-1`.
987+ */
988+ ArgumentOperand getArgumentOperand ( int index ) { none ( ) }
989+
990+ /**
991+ * Gets the argument at the specified index, or `this` if `index` is `-1`.
992+ */
993+ pragma [ noinline]
994+ final Instruction getArgument ( int index ) { result = this .getArgumentOperand ( index ) .getDef ( ) }
995+
996+ /**
997+ * Gets the number of arguments of the call, including the `this` pointer, if any.
998+ */
999+ final int getNumberOfArguments ( ) { result = count ( this .getArgumentOperand ( _) ) }
1000+
1001+ /**
1002+ * Gets the enclosing callable, if any.
1003+ */
1004+ DataFlowCallable getEnclosingCallable ( ) { none ( ) }
1005+
1006+ /**
1007+ * Gets a textual representation of this call.
1008+ */
1009+ string toString ( ) { none ( ) }
1010+
1011+ /**
1012+ * Gets the location of this call.
1013+ */
1014+ Location getLocation ( ) { none ( ) }
1015+ }
1016+
1017+ private class NormalCall extends DataFlowCall , TNormalCall {
1018+ private CallInstruction call ;
1019+
1020+ NormalCall ( ) { this = TNormalCall ( call ) }
1021+
1022+ override CallInstruction asCallInstruction ( ) { result = call }
1023+
1024+ override CallTargetOperand getCallTargetOperand ( ) { result = call .getCallTargetOperand ( ) }
1025+
1026+ override Function getStaticCallTarget ( ) { result = call .getStaticCallTarget ( ) }
1027+
1028+ override ArgumentOperand getArgumentOperand ( int index ) {
1029+ result = call .getArgumentOperand ( index )
1030+ }
1031+
1032+ override DataFlowCallable getEnclosingCallable ( ) { result = call .getEnclosingFunction ( ) }
1033+
1034+ override string toString ( ) { result = call .toString ( ) }
1035+
1036+ override Location getLocation ( ) { result = call .getLocation ( ) }
1037+ }
1038+
1039+ class SummaryCall extends DataFlowCall , TSummaryCall {
1040+ private FlowSummaryImpl:: Public:: SummarizedCallable c ;
1041+ private FlowSummaryImpl:: Private:: SummaryNode receiver ;
1042+
1043+ SummaryCall ( ) { this = TSummaryCall ( c , receiver ) }
1044+
1045+ /** Gets the data flow node that this call targets. */
1046+ FlowSummaryImpl:: Private:: SummaryNode getReceiver ( ) { result = receiver }
1047+
1048+ // override CallTargetOperand getCallTargetOperand() TODO
1049+
1050+ override Function getStaticCallTarget ( ) { // TODO: should this return DataFlowCallable?
1051+ result = c
1052+ }
1053+
1054+ // override ArgumentOperand getArgumentOperand(int index) TODO
1055+
1056+ // override DataFlowCallable getEnclosingCallable() { result = TSummarizedCallable(c) } TODO
1057+
1058+ override string toString ( ) { result = "[summary] call to " + receiver + " in " + c }
1059+
1060+ override UnknownLocation getLocation ( ) { any ( ) }
9441061}
9451062
9461063module IsUnreachableInCall {
0 commit comments