@@ -10,12 +10,39 @@ private import TranslatedElement
1010private import TranslatedExpr
1111private import TranslatedInitialization
1212private import TranslatedStmt
13+ private import VarArgs
1314
1415/**
1516 * Gets the `TranslatedFunction` that represents function `func`.
1617 */
1718TranslatedFunction getTranslatedFunction ( Function func ) { result .getAST ( ) = func }
1819
20+ /**
21+ * Gets the size, in bytes, of the variable used to represent the `...` parameter in a varargs
22+ * function. This is determined by finding the total size of all of the arguments passed to the
23+ * `...` in each call in the program, and choosing the maximum of those, with a minimum of 8 bytes.
24+ */
25+ private int getEllipsisVariableByteSize ( ) {
26+ result =
27+ max ( int variableSize |
28+ variableSize =
29+ max ( Call call , int callSize |
30+ callSize =
31+ sum ( int argIndex |
32+ isEllipsisArgumentIndex ( call , argIndex )
33+ |
34+ call .getArgument ( argIndex ) .getType ( ) .getSize ( )
35+ )
36+ |
37+ callSize
38+ )
39+ or
40+ variableSize = 8
41+ |
42+ variableSize
43+ )
44+ }
45+
1946/**
2047 * Represents the IR translation of a function. This is the root elements for
2148 * all other elements associated with this function.
@@ -60,6 +87,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
6087
6188 final private TranslatedParameter getParameter ( int index ) {
6289 result = getTranslatedParameter ( func .getParameter ( index ) )
90+ or
91+ index = getEllipsisParameterIndexForFunction ( func ) and
92+ result = getTranslatedEllipsisParameter ( func )
6393 }
6494
6595 final override Instruction getFirstInstruction ( ) { result = getInstruction ( EnterFunctionTag ( ) ) }
@@ -113,7 +143,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
113143 final override Instruction getChildSuccessor ( TranslatedElement child ) {
114144 exists ( int paramIndex |
115145 child = getParameter ( paramIndex ) and
116- if exists ( func .getParameter ( paramIndex + 1 ) )
146+ if
147+ exists ( func .getParameter ( paramIndex + 1 ) ) or
148+ getEllipsisParameterIndexForFunction ( func ) = paramIndex + 1
117149 then result = getParameter ( paramIndex + 1 ) .getFirstInstruction ( )
118150 else result = getConstructorInitList ( ) .getFirstInstruction ( )
119151 )
@@ -237,10 +269,18 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
237269 result = getReturnVariable ( )
238270 }
239271
272+ final override predicate needsUnknownOpaqueType ( int byteSize ) {
273+ byteSize = getEllipsisVariableByteSize ( )
274+ }
275+
240276 final override predicate hasTempVariable ( TempVariableTag tag , CppType type ) {
241277 tag = ReturnValueTempVar ( ) and
242278 hasReturnValue ( ) and
243279 type = getTypeForPRValue ( getReturnType ( ) )
280+ or
281+ tag = EllipsisTempVar ( ) and
282+ func .isVarargs ( ) and
283+ type = getUnknownOpaqueType ( getEllipsisVariableByteSize ( ) )
244284 }
245285
246286 /**
@@ -316,34 +356,29 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
316356}
317357
318358/**
319- * Gets the `TranslatedParameter ` that represents parameter `param`.
359+ * Gets the `TranslatedPositionalParameter ` that represents parameter `param`.
320360 */
321- TranslatedParameter getTranslatedParameter ( Parameter param ) { result .getAST ( ) = param }
361+ TranslatedPositionalParameter getTranslatedParameter ( Parameter param ) { result .getAST ( ) = param }
322362
323363/**
324- * Represents the IR translation of a function parameter, including the
325- * initialization of that parameter with the incoming argument.
364+ * Gets the `TranslatedEllipsisParameter` for function `func`, if one exists.
326365 */
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 }
366+ TranslatedEllipsisParameter getTranslatedEllipsisParameter ( Function func ) {
367+ result .getFunction ( ) = func
368+ }
335369
336- final override Function getFunction ( ) {
337- result = param .getFunction ( ) or
338- result = param .getCatchBlock ( ) .getEnclosingFunction ( )
339- }
370+ /**
371+ * The IR translation of a parameter to a function. This can be either a user-declared parameter
372+ * (`TranslatedPositionParameter`) or the synthesized parameter used to represent a `...` in a
373+ * varargs function (`TranslatedEllipsisParameter`).
374+ */
375+ abstract class TranslatedParameter extends TranslatedElement {
376+ final override TranslatedElement getChild ( int id ) { none ( ) }
340377
341378 final override Instruction getFirstInstruction ( ) {
342379 result = getInstruction ( InitializerVariableAddressTag ( ) )
343380 }
344381
345- final override TranslatedElement getChild ( int id ) { none ( ) }
346-
347382 final override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
348383 kind instanceof GotoEdge and
349384 (
@@ -368,16 +403,16 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
368403 final override predicate hasInstruction ( Opcode opcode , InstructionTag tag , CppType resultType ) {
369404 tag = InitializerVariableAddressTag ( ) and
370405 opcode instanceof Opcode:: VariableAddress and
371- resultType = getTypeForGLValue ( getVariableType ( param ) )
406+ resultType = getGLValueType ( )
372407 or
373408 tag = InitializerStoreTag ( ) and
374409 opcode instanceof Opcode:: InitializeParameter and
375- resultType = getTypeForPRValue ( getVariableType ( param ) )
410+ resultType = getPRValueType ( )
376411 or
377412 hasIndirection ( ) and
378413 tag = InitializerIndirectAddressTag ( ) and
379414 opcode instanceof Opcode:: Load and
380- resultType = getTypeForPRValue ( getVariableType ( param ) )
415+ resultType = getPRValueType ( )
381416 or
382417 hasIndirection ( ) and
383418 tag = InitializerIndirectStoreTag ( ) and
@@ -391,7 +426,7 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
391426 tag = InitializerVariableAddressTag ( ) or
392427 tag = InitializerIndirectStoreTag ( )
393428 ) and
394- result = getIRUserVariable ( getFunction ( ) , param )
429+ result = getIRVariable ( )
395430 }
396431
397432 final override Instruction getInstructionOperand ( InstructionTag tag , OperandTag operandTag ) {
@@ -416,13 +451,74 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
416451 result = getInstruction ( InitializerIndirectAddressTag ( ) )
417452 }
418453
419- predicate hasIndirection ( ) {
454+ abstract predicate hasIndirection ( ) ;
455+
456+ abstract CppType getGLValueType ( ) ;
457+
458+ abstract CppType getPRValueType ( ) ;
459+
460+ abstract IRAutomaticVariable getIRVariable ( ) ;
461+ }
462+
463+ /**
464+ * Represents the IR translation of a function parameter, including the
465+ * initialization of that parameter with the incoming argument.
466+ */
467+ class TranslatedPositionalParameter extends TranslatedParameter , TTranslatedParameter {
468+ Parameter param ;
469+
470+ TranslatedPositionalParameter ( ) { this = TTranslatedParameter ( param ) }
471+
472+ final override string toString ( ) { result = param .toString ( ) }
473+
474+ final override Locatable getAST ( ) { result = param }
475+
476+ final override Function getFunction ( ) {
477+ result = param .getFunction ( ) or
478+ result = param .getCatchBlock ( ) .getEnclosingFunction ( )
479+ }
480+
481+ final override predicate hasIndirection ( ) {
420482 exists ( Type t | t = param .getUnspecifiedType ( ) |
421483 t instanceof ArrayType or
422484 t instanceof PointerType or
423485 t instanceof ReferenceType
424486 )
425487 }
488+
489+ final override CppType getGLValueType ( ) { result = getTypeForGLValue ( getVariableType ( param ) ) }
490+
491+ final override CppType getPRValueType ( ) { result = getTypeForPRValue ( getVariableType ( param ) ) }
492+
493+ final override IRAutomaticUserVariable getIRVariable ( ) {
494+ result = getIRUserVariable ( getFunction ( ) , param )
495+ }
496+ }
497+
498+ /**
499+ * The IR translation of the synthesized parameter used to represent the `...` in a varargs
500+ * function.
501+ */
502+ class TranslatedEllipsisParameter extends TranslatedParameter , TTranslatedEllipsisParameter {
503+ Function func ;
504+
505+ TranslatedEllipsisParameter ( ) { this = TTranslatedEllipsisParameter ( func ) }
506+
507+ final override string toString ( ) { result = "..." }
508+
509+ final override Locatable getAST ( ) { result = func }
510+
511+ final override Function getFunction ( ) { result = func }
512+
513+ final override predicate hasIndirection ( ) { any ( ) }
514+
515+ final override CppType getGLValueType ( ) { result = getTypeForGLValue ( any ( UnknownType t ) ) }
516+
517+ final override CppType getPRValueType ( ) {
518+ result = getUnknownOpaqueType ( getEllipsisVariableByteSize ( ) )
519+ }
520+
521+ final override IREllipsisVariable getIRVariable ( ) { result .getEnclosingFunction ( ) = func }
426522}
427523
428524private TranslatedConstructorInitList getTranslatedConstructorInitList ( Function func ) {
0 commit comments