@@ -10,12 +10,39 @@ private import TranslatedElement
10
10
private import TranslatedExpr
11
11
private import TranslatedInitialization
12
12
private import TranslatedStmt
13
+ private import VarArgs
13
14
14
15
/**
15
16
* Gets the `TranslatedFunction` that represents function `func`.
16
17
*/
17
18
TranslatedFunction getTranslatedFunction ( Function func ) { result .getAST ( ) = func }
18
19
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
+
19
46
/**
20
47
* Represents the IR translation of a function. This is the root elements for
21
48
* all other elements associated with this function.
@@ -60,6 +87,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
60
87
61
88
final private TranslatedParameter getParameter ( int index ) {
62
89
result = getTranslatedParameter ( func .getParameter ( index ) )
90
+ or
91
+ index = getEllipsisParameterIndexForFunction ( func ) and
92
+ result = getTranslatedEllipsisParameter ( func )
63
93
}
64
94
65
95
final override Instruction getFirstInstruction ( ) { result = getInstruction ( EnterFunctionTag ( ) ) }
@@ -113,7 +143,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
113
143
final override Instruction getChildSuccessor ( TranslatedElement child ) {
114
144
exists ( int paramIndex |
115
145
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
117
149
then result = getParameter ( paramIndex + 1 ) .getFirstInstruction ( )
118
150
else result = getConstructorInitList ( ) .getFirstInstruction ( )
119
151
)
@@ -237,10 +269,18 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
237
269
result = getReturnVariable ( )
238
270
}
239
271
272
+ final override predicate needsUnknownOpaqueType ( int byteSize ) {
273
+ byteSize = getEllipsisVariableByteSize ( )
274
+ }
275
+
240
276
final override predicate hasTempVariable ( TempVariableTag tag , CppType type ) {
241
277
tag = ReturnValueTempVar ( ) and
242
278
hasReturnValue ( ) and
243
279
type = getTypeForPRValue ( getReturnType ( ) )
280
+ or
281
+ tag = EllipsisTempVar ( ) and
282
+ func .isVarargs ( ) and
283
+ type = getUnknownOpaqueType ( getEllipsisVariableByteSize ( ) )
244
284
}
245
285
246
286
/**
@@ -316,34 +356,29 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
316
356
}
317
357
318
358
/**
319
- * Gets the `TranslatedParameter ` that represents parameter `param`.
359
+ * Gets the `TranslatedPositionalParameter ` that represents parameter `param`.
320
360
*/
321
- TranslatedParameter getTranslatedParameter ( Parameter param ) { result .getAST ( ) = param }
361
+ TranslatedPositionalParameter getTranslatedParameter ( Parameter param ) { result .getAST ( ) = param }
322
362
323
363
/**
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.
326
365
*/
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
+ }
335
369
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 ( ) }
340
377
341
378
final override Instruction getFirstInstruction ( ) {
342
379
result = getInstruction ( InitializerVariableAddressTag ( ) )
343
380
}
344
381
345
- final override TranslatedElement getChild ( int id ) { none ( ) }
346
-
347
382
final override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
348
383
kind instanceof GotoEdge and
349
384
(
@@ -368,16 +403,16 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
368
403
final override predicate hasInstruction ( Opcode opcode , InstructionTag tag , CppType resultType ) {
369
404
tag = InitializerVariableAddressTag ( ) and
370
405
opcode instanceof Opcode:: VariableAddress and
371
- resultType = getTypeForGLValue ( getVariableType ( param ) )
406
+ resultType = getGLValueType ( )
372
407
or
373
408
tag = InitializerStoreTag ( ) and
374
409
opcode instanceof Opcode:: InitializeParameter and
375
- resultType = getTypeForPRValue ( getVariableType ( param ) )
410
+ resultType = getPRValueType ( )
376
411
or
377
412
hasIndirection ( ) and
378
413
tag = InitializerIndirectAddressTag ( ) and
379
414
opcode instanceof Opcode:: Load and
380
- resultType = getTypeForPRValue ( getVariableType ( param ) )
415
+ resultType = getPRValueType ( )
381
416
or
382
417
hasIndirection ( ) and
383
418
tag = InitializerIndirectStoreTag ( ) and
@@ -391,7 +426,7 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
391
426
tag = InitializerVariableAddressTag ( ) or
392
427
tag = InitializerIndirectStoreTag ( )
393
428
) and
394
- result = getIRUserVariable ( getFunction ( ) , param )
429
+ result = getIRVariable ( )
395
430
}
396
431
397
432
final override Instruction getInstructionOperand ( InstructionTag tag , OperandTag operandTag ) {
@@ -416,13 +451,74 @@ class TranslatedParameter extends TranslatedElement, TTranslatedParameter {
416
451
result = getInstruction ( InitializerIndirectAddressTag ( ) )
417
452
}
418
453
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 ( ) {
420
482
exists ( Type t | t = param .getUnspecifiedType ( ) |
421
483
t instanceof ArrayType or
422
484
t instanceof PointerType or
423
485
t instanceof ReferenceType
424
486
)
425
487
}
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 }
426
522
}
427
523
428
524
private TranslatedConstructorInitList getTranslatedConstructorInitList ( Function func ) {
0 commit comments