@@ -10,6 +10,7 @@ private newtype TNode =
1010 MkInstructionNode ( IR:: Instruction insn ) or
1111 MkSsaNode ( SsaDefinition ssa ) or
1212 MkGlobalFunctionNode ( Function f ) or
13+ MkImplicitVarargsSlice ( CallExpr c ) { c .getTarget ( ) .isVariadic ( ) and not c .hasEllipsis ( ) } or
1314 MkSummarizedParameterNode ( SummarizedCallable c , int i ) {
1415 FlowSummaryImpl:: Private:: summaryParameterNodeRange ( c , i )
1516 } or
@@ -426,6 +427,41 @@ module Public {
426427 override ResultNode getAResult ( ) { result .getRoot ( ) = this .getExpr ( ) }
427428 }
428429
430+ /**
431+ * An implicit varargs slice creation expression.
432+ *
433+ * A variadic function like `f(t1 T1, ..., Tm tm, A... x)` actually sees the
434+ * varargs parameter as a slice `[]A`. A call `f(t1, ..., tm, x1, ..., xn)`
435+ * desugars to `f(t1, ..., tm, []A{x1, ..., xn})`, and this node corresponds
436+ * to this implicit slice creation.
437+ */
438+ class ImplicitVarargsSlice extends Node , MkImplicitVarargsSlice {
439+ CallNode call ;
440+
441+ ImplicitVarargsSlice ( ) { this = MkImplicitVarargsSlice ( call .getCall ( ) ) }
442+
443+ override ControlFlow:: Root getRoot ( ) { result = call .getRoot ( ) }
444+
445+ /** Gets the call containing this varargs slice creation argument. */
446+ CallNode getCallNode ( ) { result = call }
447+
448+ override Type getType ( ) {
449+ exists ( Function f | f = call .getTarget ( ) |
450+ result = f .getParameterType ( f .getNumParameter ( ) - 1 )
451+ )
452+ }
453+
454+ override string getNodeKind ( ) { result = "implicit varargs slice" }
455+
456+ override string toString ( ) { result = "[]type{args}" }
457+
458+ override predicate hasLocationInfo (
459+ string filepath , int startline , int startcolumn , int endline , int endcolumn
460+ ) {
461+ call .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
462+ }
463+ }
464+
429465 /**
430466 * Gets a possible target of call `cn`.class
431467 *
0 commit comments