@@ -406,42 +406,6 @@ class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSi
406
406
}
407
407
}
408
408
409
- class TranslatedStructorCallSideEffects extends TranslatedCallSideEffects {
410
- TranslatedStructorCallSideEffects ( ) {
411
- getParent ( ) .( TranslatedStructorCall ) .hasQualifier ( ) and
412
- getASideEffectOpcode ( expr , - 1 ) instanceof WriteSideEffectOpcode
413
- }
414
-
415
- override predicate hasInstruction ( Opcode opcode , InstructionTag tag , CppType t ) {
416
- tag instanceof OnlyInstructionTag and
417
- t = getTypeForPRValue ( expr .getTarget ( ) .getDeclaringType ( ) ) and
418
- opcode = getASideEffectOpcode ( expr , - 1 ) .( WriteSideEffectOpcode )
419
- }
420
-
421
- override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
422
- (
423
- if exists ( getChild ( 0 ) )
424
- then result = getChild ( 0 ) .getFirstInstruction ( )
425
- else result = getParent ( ) .getChildSuccessor ( this )
426
- ) and
427
- tag = OnlyInstructionTag ( ) and
428
- kind instanceof GotoEdge
429
- }
430
-
431
- override Instruction getFirstInstruction ( ) { result = getInstruction ( OnlyInstructionTag ( ) ) }
432
-
433
- override Instruction getInstructionRegisterOperand ( InstructionTag tag , OperandTag operandTag ) {
434
- tag instanceof OnlyInstructionTag and
435
- operandTag instanceof AddressOperandTag and
436
- result = getParent ( ) .( TranslatedStructorCall ) .getQualifierResult ( )
437
- }
438
-
439
- final override int getInstructionIndex ( InstructionTag tag ) {
440
- tag = OnlyInstructionTag ( ) and
441
- result = - 1
442
- }
443
- }
444
-
445
409
/** Returns the sort group index for argument read side effects. */
446
410
private int argumentReadGroup ( ) { result = 1 }
447
411
@@ -502,19 +466,22 @@ abstract class TranslatedSideEffect extends TranslatedElement {
502
466
/**
503
467
* The IR translation of a single argument side effect for a call.
504
468
*/
505
- class TranslatedArgumentSideEffect extends TranslatedSideEffect , TTranslatedArgumentSideEffect {
469
+ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
506
470
Call call ;
507
- Expr arg ;
508
471
int index ;
509
472
SideEffectOpcode sideEffectOpcode ;
510
473
511
- TranslatedArgumentSideEffect ( ) {
512
- this = TTranslatedArgumentSideEffect ( call , arg , index , sideEffectOpcode )
513
- }
514
-
515
- override Locatable getAST ( ) { result = arg }
474
+ // All subclass charpreds must bind the `index` field.
475
+ bindingset [ index]
476
+ TranslatedArgumentSideEffect ( ) { any ( ) }
516
477
517
- Expr getExpr ( ) { result = arg }
478
+ override string toString ( ) {
479
+ isWrite ( ) and
480
+ result = "(write side effect for " + getArgString ( ) + ")"
481
+ or
482
+ not isWrite ( ) and
483
+ result = "(read side effect for " + getArgString ( ) + ")"
484
+ }
518
485
519
486
override Call getPrimaryExpr ( ) { result = call }
520
487
@@ -523,17 +490,29 @@ class TranslatedArgumentSideEffect extends TranslatedSideEffect, TTranslatedArgu
523
490
if isWrite ( ) then group = argumentWriteGroup ( ) else group = argumentReadGroup ( )
524
491
}
525
492
526
- predicate isWrite ( ) { sideEffectOpcode instanceof WriteSideEffectOpcode }
493
+ override Instruction getPrimaryInstructionForSideEffect ( InstructionTag tag ) {
494
+ tag = OnlyInstructionTag ( ) and
495
+ result = getTranslatedCallInstruction ( call )
496
+ }
527
497
528
- override string toString ( ) {
529
- isWrite ( ) and
530
- result = "(write side effect for " + arg .toString ( ) + ")"
531
- or
532
- not isWrite ( ) and
533
- result = "(read side effect for " + arg .toString ( ) + ")"
498
+ final override int getInstructionIndex ( InstructionTag tag ) {
499
+ tag = OnlyInstructionTag ( ) and
500
+ result = index
534
501
}
535
502
536
- override predicate sideEffectInstruction ( Opcode opcode , CppType type ) {
503
+ /**
504
+ * Gets the `TranslatedFunction` containing this expression.
505
+ */
506
+ final TranslatedFunction getEnclosingFunction ( ) {
507
+ result = getTranslatedFunction ( call .getEnclosingFunction ( ) )
508
+ }
509
+
510
+ /**
511
+ * Gets the `Function` containing this expression.
512
+ */
513
+ final override Function getFunction ( ) { result = call .getEnclosingFunction ( ) }
514
+
515
+ final override predicate sideEffectInstruction ( Opcode opcode , CppType type ) {
537
516
opcode = sideEffectOpcode and
538
517
(
539
518
isWrite ( ) and
@@ -542,36 +521,21 @@ class TranslatedArgumentSideEffect extends TranslatedSideEffect, TTranslatedArgu
542
521
type = getUnknownType ( )
543
522
or
544
523
not opcode instanceof BufferAccessOpcode and
545
- exists ( Type baseType | baseType = arg . getUnspecifiedType ( ) . ( DerivedType ) . getBaseType ( ) |
546
- if baseType instanceof VoidType
524
+ exists ( Type indirectionType | indirectionType = getIndirectionType ( ) |
525
+ if indirectionType instanceof VoidType
547
526
then type = getUnknownType ( )
548
- else type = getTypeForPRValueOrUnknown ( baseType )
527
+ else type = getTypeForPRValueOrUnknown ( indirectionType )
549
528
)
550
- or
551
- index = - 1 and
552
- not arg .getUnspecifiedType ( ) instanceof DerivedType and
553
- type = getTypeForPRValueOrUnknown ( arg .getUnspecifiedType ( ) )
554
529
)
555
530
or
556
531
not isWrite ( ) and
557
532
type = getVoidType ( )
558
533
)
559
534
}
560
535
561
- override Instruction getInstructionRegisterOperand ( InstructionTag tag , OperandTag operandTag ) {
562
- tag instanceof OnlyInstructionTag and
563
- operandTag instanceof AddressOperandTag and
564
- result = getTranslatedExpr ( arg ) .getResult ( )
565
- or
566
- tag instanceof OnlyInstructionTag and
567
- operandTag instanceof BufferSizeOperandTag and
568
- result =
569
- getTranslatedExpr ( call .getArgument ( call .getTarget ( )
570
- .( SideEffectFunction )
571
- .getParameterSizeIndex ( index ) ) .getFullyConverted ( ) ) .getResult ( )
572
- }
573
-
574
- override CppType getInstructionMemoryOperandType ( InstructionTag tag , TypedOperandTag operandTag ) {
536
+ final override CppType getInstructionMemoryOperandType (
537
+ InstructionTag tag , TypedOperandTag operandTag
538
+ ) {
575
539
not isWrite ( ) and
576
540
if sideEffectOpcode instanceof BufferAccessOpcode
577
541
then
@@ -581,12 +545,7 @@ class TranslatedArgumentSideEffect extends TranslatedSideEffect, TTranslatedArgu
581
545
else
582
546
exists ( Type operandType |
583
547
tag instanceof OnlyInstructionTag and
584
- operandType = arg .getType ( ) .getUnspecifiedType ( ) .( DerivedType ) .getBaseType ( ) and
585
- operandTag instanceof SideEffectOperandTag
586
- or
587
- tag instanceof OnlyInstructionTag and
588
- operandType = arg .getType ( ) .getUnspecifiedType ( ) and
589
- not operandType instanceof DerivedType and
548
+ operandType = getIndirectionType ( ) and
590
549
operandTag instanceof SideEffectOperandTag
591
550
|
592
551
// If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will
@@ -595,25 +554,87 @@ class TranslatedArgumentSideEffect extends TranslatedSideEffect, TTranslatedArgu
595
554
)
596
555
}
597
556
598
- override Instruction getPrimaryInstructionForSideEffect ( InstructionTag tag ) {
599
- tag = OnlyInstructionTag ( ) and
600
- result = getTranslatedCallInstruction ( call )
557
+ final override Instruction getInstructionRegisterOperand ( InstructionTag tag , OperandTag operandTag ) {
558
+ tag instanceof OnlyInstructionTag and
559
+ operandTag instanceof AddressOperandTag and
560
+ result = getArgInstruction ( )
561
+ or
562
+ tag instanceof OnlyInstructionTag and
563
+ operandTag instanceof BufferSizeOperandTag and
564
+ result =
565
+ getTranslatedExpr ( call .getArgument ( call .getTarget ( )
566
+ .( SideEffectFunction )
567
+ .getParameterSizeIndex ( index ) ) .getFullyConverted ( ) ) .getResult ( )
601
568
}
602
569
603
- final override int getInstructionIndex ( InstructionTag tag ) {
604
- tag = OnlyInstructionTag ( ) and
605
- result = index
570
+ /** Holds if this side effect is a write side effect, rather than a read side effect. */
571
+ final predicate isWrite ( ) { sideEffectOpcode instanceof WriteSideEffectOpcode }
572
+
573
+ /** Gets a text representation of the argument. */
574
+ abstract string getArgString ( ) ;
575
+
576
+ /** Gets the `Instruction` whose result is the value of the argument. */
577
+ abstract Instruction getArgInstruction ( ) ;
578
+
579
+ /** Gets the type pointed to by the argument. */
580
+ abstract Type getIndirectionType ( ) ;
581
+ }
582
+
583
+ /**
584
+ * The IR translation of an argument side effect where the argument has an `Expr` object in the AST.
585
+ *
586
+ * This generally applies to all positional arguments, as well as qualifier (`this`) arguments for
587
+ * calls other than constructor calls.
588
+ */
589
+ class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect ,
590
+ TTranslatedArgumentExprSideEffect {
591
+ Expr arg ;
592
+
593
+ TranslatedArgumentExprSideEffect ( ) {
594
+ this = TTranslatedArgumentExprSideEffect ( call , arg , index , sideEffectOpcode )
606
595
}
607
596
608
- /**
609
- * Gets the `TranslatedFunction` containing this expression.
610
- */
611
- final TranslatedFunction getEnclosingFunction ( ) {
612
- result = getTranslatedFunction ( arg .getEnclosingFunction ( ) )
597
+ final override Locatable getAST ( ) { result = arg }
598
+
599
+ final override Type getIndirectionType ( ) {
600
+ result = arg .getUnspecifiedType ( ) .( DerivedType ) .getBaseType ( )
601
+ or
602
+ // Sometimes the qualifier type gets the type of the class itself, rather than a pointer to the
603
+ // class.
604
+ index = - 1 and
605
+ not arg .getUnspecifiedType ( ) instanceof DerivedType and
606
+ result = arg .getUnspecifiedType ( )
613
607
}
614
608
615
- /**
616
- * Gets the `Function` containing this expression.
617
- */
618
- override Function getFunction ( ) { result = arg .getEnclosingFunction ( ) }
609
+ final override string getArgString ( ) { result = arg .toString ( ) }
610
+
611
+ final override Instruction getArgInstruction ( ) { result = getTranslatedExpr ( arg ) .getResult ( ) }
612
+ }
613
+
614
+ /**
615
+ * The IR translation of an argument side effect for `*this` on a call, where there is no `Expr`
616
+ * object that represents the `this` argument.
617
+ *
618
+ * The applies only to constructor calls, as the AST has explioit qualifier `Expr`s for all other
619
+ * calls to non-static member functions.
620
+ */
621
+ class TranslatedStructorQualifierSideEffect extends TranslatedArgumentSideEffect ,
622
+ TTranslatedStructorQualifierSideEffect {
623
+ TranslatedStructorQualifierSideEffect ( ) {
624
+ this = TTranslatedStructorQualifierSideEffect ( call , sideEffectOpcode ) and
625
+ index = - 1
626
+ }
627
+
628
+ final override Locatable getAST ( ) { result = call }
629
+
630
+ final override Type getIndirectionType ( ) { result = call .getTarget ( ) .getDeclaringType ( ) }
631
+
632
+ final override string getArgString ( ) { result = "this" }
633
+
634
+ final override Instruction getArgInstruction ( ) {
635
+ exists ( TranslatedStructorCall structorCall |
636
+ structorCall .getExpr ( ) = call and
637
+ result = structorCall .getQualifierResult ( )
638
+ )
639
+ }
619
640
}
0 commit comments