@@ -406,42 +406,6 @@ class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSi
406406 }
407407}
408408
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-
445409/** Returns the sort group index for argument read side effects. */
446410private int argumentReadGroup ( ) { result = 1 }
447411
@@ -502,19 +466,22 @@ abstract class TranslatedSideEffect extends TranslatedElement {
502466/**
503467 * The IR translation of a single argument side effect for a call.
504468 */
505- class TranslatedArgumentSideEffect extends TranslatedSideEffect , TTranslatedArgumentSideEffect {
469+ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
506470 Call call ;
507- Expr arg ;
508471 int index ;
509472 SideEffectOpcode sideEffectOpcode ;
510473
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 ( ) }
516477
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+ }
518485
519486 override Call getPrimaryExpr ( ) { result = call }
520487
@@ -523,17 +490,29 @@ class TranslatedArgumentSideEffect extends TranslatedSideEffect, TTranslatedArgu
523490 if isWrite ( ) then group = argumentWriteGroup ( ) else group = argumentReadGroup ( )
524491 }
525492
526- predicate isWrite ( ) { sideEffectOpcode instanceof WriteSideEffectOpcode }
493+ override Instruction getPrimaryInstructionForSideEffect ( InstructionTag tag ) {
494+ tag = OnlyInstructionTag ( ) and
495+ result = getTranslatedCallInstruction ( call )
496+ }
527497
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
534501 }
535502
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 ) {
537516 opcode = sideEffectOpcode and
538517 (
539518 isWrite ( ) and
@@ -542,36 +521,21 @@ class TranslatedArgumentSideEffect extends TranslatedSideEffect, TTranslatedArgu
542521 type = getUnknownType ( )
543522 or
544523 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
547526 then type = getUnknownType ( )
548- else type = getTypeForPRValueOrUnknown ( baseType )
527+ else type = getTypeForPRValueOrUnknown ( indirectionType )
549528 )
550- or
551- index = - 1 and
552- not arg .getUnspecifiedType ( ) instanceof DerivedType and
553- type = getTypeForPRValueOrUnknown ( arg .getUnspecifiedType ( ) )
554529 )
555530 or
556531 not isWrite ( ) and
557532 type = getVoidType ( )
558533 )
559534 }
560535
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+ ) {
575539 not isWrite ( ) and
576540 if sideEffectOpcode instanceof BufferAccessOpcode
577541 then
@@ -581,12 +545,7 @@ class TranslatedArgumentSideEffect extends TranslatedSideEffect, TTranslatedArgu
581545 else
582546 exists ( Type operandType |
583547 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
590549 operandTag instanceof SideEffectOperandTag
591550 |
592551 // 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
595554 )
596555 }
597556
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 ( )
601568 }
602569
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 )
606595 }
607596
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 ( )
613607 }
614608
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+ }
619640}
0 commit comments