@@ -16,6 +16,32 @@ private import TranslatedStmt
1616 */
1717TranslatedFunction getTranslatedFunction ( Function func ) { result .getAST ( ) = func }
1818
19+ /**
20+ * Gets the size, in bytes, of the variable used to represent the `...` parameter in a varargs
21+ * function. This is determined by finding the total size of all of the arguments passed to the
22+ * `...` in each call in the program, and choosing the maximum of those, with a minimum of 8 bytes.
23+ */
24+ private int getEllipsisVariableByteSize ( ) {
25+ result =
26+ max ( int variableSize |
27+ variableSize =
28+ max ( Call call , int callSize |
29+ callSize =
30+ sum ( int argIndex |
31+ call .isEllipsisArgumentIndex ( argIndex )
32+ |
33+ call .getArgument ( argIndex ) .getType ( ) .getSize ( )
34+ )
35+ |
36+ callSize
37+ )
38+ or
39+ variableSize = 8
40+ |
41+ variableSize
42+ )
43+ }
44+
1945/**
2046 * Represents the IR translation of a function. This is the root elements for
2147 * all other elements associated with this function.
@@ -60,6 +86,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
6086
6187 final private TranslatedParameter getParameter ( int index ) {
6288 result = getTranslatedParameter ( func .getParameter ( index ) )
89+ or
90+ index = func .getEllipsisParameterIndex ( ) and
91+ result = getTranslatedEllipsisParameter ( func )
6392 }
6493
6594 final override Instruction getFirstInstruction ( ) { result = getInstruction ( EnterFunctionTag ( ) ) }
@@ -113,7 +142,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
113142 final override Instruction getChildSuccessor ( TranslatedElement child ) {
114143 exists ( int paramIndex |
115144 child = getParameter ( paramIndex ) and
116- if exists ( func .getParameter ( paramIndex + 1 ) )
145+ if
146+ exists ( func .getParameter ( paramIndex + 1 ) ) or
147+ func .getEllipsisParameterIndex ( ) = paramIndex + 1
117148 then result = getParameter ( paramIndex + 1 ) .getFirstInstruction ( )
118149 else result = getConstructorInitList ( ) .getFirstInstruction ( )
119150 )
@@ -237,10 +268,18 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
237268 result = getReturnVariable ( )
238269 }
239270
271+ final override predicate needsUnknownOpaqueType ( int byteSize ) {
272+ byteSize = getEllipsisVariableByteSize ( )
273+ }
274+
240275 final override predicate hasTempVariable ( TempVariableTag tag , CppType type ) {
241276 tag = ReturnValueTempVar ( ) and
242277 hasReturnValue ( ) and
243278 type = getTypeForPRValue ( getReturnType ( ) )
279+ or
280+ tag = EllipsisTempVar ( ) and
281+ func .isVarargs ( ) and
282+ type = getUnknownOpaqueType ( getEllipsisVariableByteSize ( ) )
244283 }
245284
246285 /**
@@ -316,34 +355,29 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
316355}
317356
318357/**
319- * Gets the `TranslatedParameter ` that represents parameter `param`.
358+ * Gets the `TranslatedPositionalParameter ` that represents parameter `param`.
320359 */
321- TranslatedParameter getTranslatedParameter ( Parameter param ) { result .getAST ( ) = param }
360+ TranslatedPositionalParameter getTranslatedParameter ( Parameter param ) { result .getAST ( ) = param }
322361
323362/**
324- * Represents the IR translation of a function parameter, including the
325- * initialization of that parameter with the incoming argument.
363+ * Gets the `TranslatedEllipsisParameter` for function `func`, if one exists.
326364 */
327- class TranslatedParameter extends TranslatedElement , TTranslatedParameter {
328- Parameter param ;
329-
330- TranslatedParameter ( ) { this = TTranslatedParameter ( param ) }
331-
332- final override string toString ( ) { result = param .toString ( ) }
333-
334- final override Locatable getAST ( ) { result = param }
365+ TranslatedEllipsisParameter getTranslatedEllipsisParameter ( Function func ) {
366+ result .getFunction ( ) = func
367+ }
335368
336- final override Function getFunction ( ) {
337- result = param .getFunction ( ) or
338- result = param .getCatchBlock ( ) .getEnclosingFunction ( )
339- }
369+ /**
370+ * The IR translation of a parameter to a function. This can be either a user-declared parameter
371+ * (`TranslatedPositionParameter`) or the synthesized parameter used to represent a `...` in a
372+ * varargs function (`TranslatedEllipsisParameter`).
373+ */
374+ abstract class TranslatedParameter extends TranslatedElement {
375+ final override TranslatedElement getChild ( int id ) { none ( ) }
340376
341377 final override Instruction getFirstInstruction ( ) {
342378 result = getInstruction ( InitializerVariableAddressTag ( ) )
343379 }
344380
345- final override TranslatedElement getChild ( int id ) { none ( ) }
346-
347381 final override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
348382 kind instanceof GotoEdge and
349383 (
@@ -368,16 +402,16 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
368402 final override predicate hasInstruction ( Opcode opcode , InstructionTag tag , CppType resultType ) {
369403 tag = InitializerVariableAddressTag ( ) and
370404 opcode instanceof Opcode:: VariableAddress and
371- resultType = getTypeForGLValue ( getVariableType ( param ) )
405+ resultType = getGLValueType ( )
372406 or
373407 tag = InitializerStoreTag ( ) and
374408 opcode instanceof Opcode:: InitializeParameter and
375- resultType = getTypeForPRValue ( getVariableType ( param ) )
409+ resultType = getPRValueType ( )
376410 or
377411 hasIndirection ( ) and
378412 tag = InitializerIndirectAddressTag ( ) and
379413 opcode instanceof Opcode:: Load and
380- resultType = getTypeForPRValue ( getVariableType ( param ) )
414+ resultType = getPRValueType ( )
381415 or
382416 hasIndirection ( ) and
383417 tag = InitializerIndirectStoreTag ( ) and
@@ -391,7 +425,7 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
391425 tag = InitializerVariableAddressTag ( ) or
392426 tag = InitializerIndirectStoreTag ( )
393427 ) and
394- result = getIRUserVariable ( getFunction ( ) , param )
428+ result = getIRVariable ( )
395429 }
396430
397431 final override Instruction getInstructionOperand ( InstructionTag tag , OperandTag operandTag ) {
@@ -416,13 +450,74 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
416450 result = getInstruction ( InitializerIndirectAddressTag ( ) )
417451 }
418452
419- predicate hasIndirection ( ) {
453+ abstract predicate hasIndirection ( ) ;
454+
455+ abstract CppType getGLValueType ( ) ;
456+
457+ abstract CppType getPRValueType ( ) ;
458+
459+ abstract IRAutomaticVariable getIRVariable ( ) ;
460+ }
461+
462+ /**
463+ * Represents the IR translation of a function parameter, including the
464+ * initialization of that parameter with the incoming argument.
465+ */
466+ class TranslatedPositionalParameter extends TranslatedParameter , TTranslatedParameter {
467+ Parameter param ;
468+
469+ TranslatedPositionalParameter ( ) { this = TTranslatedParameter ( param ) }
470+
471+ final override string toString ( ) { result = param .toString ( ) }
472+
473+ final override Locatable getAST ( ) { result = param }
474+
475+ final override Function getFunction ( ) {
476+ result = param .getFunction ( ) or
477+ result = param .getCatchBlock ( ) .getEnclosingFunction ( )
478+ }
479+
480+ final override predicate hasIndirection ( ) {
420481 exists ( Type t | t = param .getUnspecifiedType ( ) |
421482 t instanceof ArrayType or
422483 t instanceof PointerType or
423484 t instanceof ReferenceType
424485 )
425486 }
487+
488+ final override CppType getGLValueType ( ) { result = getTypeForGLValue ( getVariableType ( param ) ) }
489+
490+ final override CppType getPRValueType ( ) { result = getTypeForPRValue ( getVariableType ( param ) ) }
491+
492+ final override IRAutomaticUserVariable getIRVariable ( ) {
493+ result = getIRUserVariable ( getFunction ( ) , param )
494+ }
495+ }
496+
497+ /**
498+ * The IR translation of the synthesized parameter used to represent the `...` in a varargs
499+ * function.
500+ */
501+ class TranslatedEllipsisParameter extends TranslatedParameter , TTranslatedEllipsisParameter {
502+ Function func ;
503+
504+ TranslatedEllipsisParameter ( ) { this = TTranslatedEllipsisParameter ( func ) }
505+
506+ final override string toString ( ) { result = "..." }
507+
508+ final override Locatable getAST ( ) { result = func }
509+
510+ final override Function getFunction ( ) { result = func }
511+
512+ final override predicate hasIndirection ( ) { any ( ) }
513+
514+ final override CppType getGLValueType ( ) { result = getTypeForGLValue ( any ( UnknownType t ) ) }
515+
516+ final override CppType getPRValueType ( ) {
517+ result = getUnknownOpaqueType ( getEllipsisVariableByteSize ( ) )
518+ }
519+
520+ final override IREllipsisVariable getIRVariable ( ) { result .getEnclosingFunction ( ) = func }
426521}
427522
428523private TranslatedConstructorInitList getTranslatedConstructorInitList ( Function func ) {
0 commit comments