@@ -246,14 +246,6 @@ private module IteratorIndirections {
246
246
baseType = super .getValueType ( )
247
247
}
248
248
249
- override predicate isAdditionalDereference ( Instruction deref , Operand address ) {
250
- exists ( CallInstruction call |
251
- operandForFullyConvertedCall ( getAUse ( deref ) , call ) and
252
- this = call .getStaticCallTarget ( ) .getClassAndName ( "operator*" ) and
253
- address = call .getThisArgumentOperand ( )
254
- )
255
- }
256
-
257
249
override predicate isAdditionalWrite ( Node0Impl value , Operand address , boolean certain ) {
258
250
exists ( CallInstruction call | call .getArgumentOperand ( 0 ) = value .asOperand ( ) |
259
251
this = call .getStaticCallTarget ( ) .getClassAndName ( "operator=" ) and
@@ -262,16 +254,6 @@ private module IteratorIndirections {
262
254
)
263
255
}
264
256
265
- override predicate isAdditionalTaintStep ( Node node1 , Node node2 ) {
266
- exists ( CallInstruction call |
267
- // Taint through `operator+=` and `operator-=` on iterators.
268
- call .getStaticCallTarget ( ) instanceof Iterator:: IteratorAssignArithmeticOperator and
269
- node2 .( IndirectArgumentOutNode ) .getPreUpdateNode ( ) = node1 and
270
- node1 .( IndirectOperand ) .hasOperandAndIndirectionIndex ( call .getArgumentOperand ( 0 ) , _) and
271
- node1 .getType ( ) .getUnspecifiedType ( ) = this
272
- )
273
- }
274
-
275
257
override predicate isAdditionalConversionFlow ( Operand opFrom , Instruction instrTo ) {
276
258
// This is a bit annoying: Consider the following snippet:
277
259
// ```
@@ -589,230 +571,6 @@ private class BaseCallInstruction extends BaseSourceVariableInstruction, CallIns
589
571
590
572
cached
591
573
private module Cached {
592
- private import semmle.code.cpp.models.interfaces.Iterator as Interfaces
593
- private import semmle.code.cpp.models.implementations.Iterator as Iterator
594
- private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as IO
595
-
596
- /**
597
- * Holds if `next` is a instruction with a memory result that potentially
598
- * updates the memory produced by `prev`.
599
- */
600
- private predicate memorySucc ( Instruction prev , Instruction next ) {
601
- prev = next .( ChiInstruction ) .getTotal ( )
602
- or
603
- // Phi inputs can be inexact.
604
- prev = next .( PhiInstruction ) .getAnInputOperand ( ) .getAnyDef ( )
605
- or
606
- prev = next .( CopyInstruction ) .getSourceValue ( )
607
- or
608
- exists ( ReadSideEffectInstruction read |
609
- next = read .getPrimaryInstruction ( ) and
610
- isAdditionalConversionFlow ( _, next ) and
611
- prev = read .getSideEffectOperand ( ) .getAnyDef ( )
612
- )
613
- }
614
-
615
- /**
616
- * Holds if `iteratorDerefAddress` is an address of an iterator dereference (i.e., `*it`)
617
- * that is used for a write operation that writes the value `value`. The `memory` instruction
618
- * represents the memory that the IR's SSA analysis determined was read by the call to `operator*`.
619
- *
620
- * The `numberOfLoads` integer represents the number of dereferences this write corresponds to
621
- * on the underlying container that produced the iterator.
622
- */
623
- private predicate isChiAfterIteratorDef (
624
- Instruction memory , Operand iteratorDerefAddress , Node0Impl value , int numberOfLoads
625
- ) {
626
- exists (
627
- BaseSourceVariableInstruction iteratorBase , ReadSideEffectInstruction read ,
628
- Operand iteratorAddress
629
- |
630
- numberOfLoads >= 0 and
631
- isDef ( _, value , iteratorDerefAddress , iteratorBase , numberOfLoads + 2 , 0 ) and
632
- isUse ( _, iteratorAddress , iteratorBase , numberOfLoads + 1 , 0 ) and
633
- iteratorBase .getResultType ( ) instanceof Interfaces:: Iterator and
634
- isDereference ( iteratorAddress .getDef ( ) , read .getArgumentDef ( ) .getAUse ( ) , _) and
635
- memory = read .getSideEffectOperand ( ) .getAnyDef ( )
636
- )
637
- }
638
-
639
- private predicate isSource ( Instruction instr , Operand iteratorAddress , int numberOfLoads ) {
640
- getAUse ( instr ) = iteratorAddress and
641
- exists ( BaseSourceVariableInstruction iteratorBase |
642
- iteratorBase .getResultType ( ) instanceof Interfaces:: Iterator and
643
- not iteratorBase .getResultType ( ) instanceof Cpp:: PointerType and
644
- isUse ( _, iteratorAddress , iteratorBase , numberOfLoads - 1 , 0 )
645
- )
646
- }
647
-
648
- private predicate isSink ( Instruction instr , CallInstruction call ) {
649
- getAUse ( instr ) .( ArgumentOperand ) .getCall ( ) = call and
650
- // Only include operations that may modify the object that the iterator points to.
651
- // The following is a non-exhaustive list of things that may modify the value of the
652
- // iterator, but never the value of what the iterator points to.
653
- // The more things we can exclude here, the faster the small dataflow-like analysis
654
- // done by `convertsIntoArgument` will converge.
655
- not exists ( Function f | f = call .getStaticCallTarget ( ) |
656
- f instanceof Iterator:: IteratorCrementOperator or
657
- f instanceof Iterator:: IteratorBinaryArithmeticOperator or
658
- f instanceof Iterator:: IteratorAssignArithmeticOperator or
659
- f instanceof Iterator:: IteratorCrementMemberOperator or
660
- f instanceof Iterator:: IteratorBinaryArithmeticMemberOperator or
661
- f instanceof Iterator:: IteratorAssignArithmeticMemberOperator or
662
- f instanceof Iterator:: IteratorAssignmentMemberOperator
663
- )
664
- }
665
-
666
- private predicate convertsIntoArgumentFwd ( Instruction instr ) {
667
- isSource ( instr , _, _)
668
- or
669
- exists ( Instruction prev | convertsIntoArgumentFwd ( prev ) |
670
- conversionFlow ( unique( | | getAUse ( prev ) ) , instr , false , _)
671
- )
672
- }
673
-
674
- private predicate convertsIntoArgumentRev ( Instruction instr ) {
675
- convertsIntoArgumentFwd ( instr ) and
676
- (
677
- isSink ( instr , _)
678
- or
679
- exists ( Instruction next | convertsIntoArgumentRev ( next ) |
680
- conversionFlow ( unique( | | getAUse ( instr ) ) , next , false , _)
681
- )
682
- )
683
- }
684
-
685
- private predicate convertsIntoArgument (
686
- Operand iteratorAddress , CallInstruction call , int numberOfLoads
687
- ) {
688
- exists ( Instruction iteratorAddressDef |
689
- isSource ( iteratorAddressDef , iteratorAddress , numberOfLoads ) and
690
- isSink ( iteratorAddressDef , call ) and
691
- convertsIntoArgumentRev ( pragma [ only_bind_into ] ( iteratorAddressDef ) )
692
- )
693
- }
694
-
695
- private predicate isChiAfterIteratorArgument (
696
- Instruction memory , Operand iteratorAddress , int numberOfLoads
697
- ) {
698
- // Ideally, `iteratorAddress` would be an `ArgumentOperand`, but there might be
699
- // various conversions applied to it before it becomes an argument.
700
- // So we do a small amount of flow to find the call that the iterator is passed to.
701
- exists ( CallInstruction call | convertsIntoArgument ( iteratorAddress , call , numberOfLoads ) |
702
- exists ( ReadSideEffectInstruction read |
703
- read .getPrimaryInstruction ( ) = call and
704
- read .getSideEffectOperand ( ) .getAnyDef ( ) = memory
705
- )
706
- or
707
- exists ( LoadInstruction load |
708
- iteratorAddress .getDef ( ) = load and
709
- memory = load .getSourceValueOperand ( ) .getAnyDef ( )
710
- )
711
- )
712
- }
713
-
714
- /**
715
- * Holds if `iterator` is a `StoreInstruction` that stores the result of some function
716
- * returning an iterator into an address computed started at `containerBase`.
717
- *
718
- * For example, given a declaration like `std::vector<int>::iterator it = v.begin()`,
719
- * the `iterator` will be the `StoreInstruction` generated by the write to `it`, and
720
- * `containerBase` will be the address of `v`.
721
- */
722
- private predicate isChiAfterBegin (
723
- BaseSourceVariableInstruction containerBase , StoreInstruction iterator
724
- ) {
725
- exists (
726
- CallInstruction getIterator , Iterator:: GetIteratorFunction getIteratorFunction ,
727
- IO:: FunctionInput input , int i
728
- |
729
- getIterator = iterator .getSourceValue ( ) and
730
- getIteratorFunction = getIterator .getStaticCallTarget ( ) and
731
- getIteratorFunction .getsIterator ( input , _) and
732
- isDef ( _, any ( Node0Impl n | n .asInstruction ( ) = iterator ) , _, _, 1 , 0 ) and
733
- input .isParameterDerefOrQualifierObject ( i ) and
734
- isUse ( _, getIterator .getArgumentOperand ( i ) , containerBase , 0 , 0 )
735
- )
736
- }
737
-
738
- /**
739
- * Holds if `iteratorAddress` is an address of an iterator that is used for
740
- * a read operation. The `memory` instruction represents the memory that
741
- * the IR's SSA analysis determined was read by the call to `operator*`.
742
- *
743
- * Finally, the `numberOfLoads` integer represents the number of dereferences
744
- * this read corresponds to on the underlying container that produced the iterator.
745
- */
746
- private predicate isChiBeforeIteratorUse (
747
- Operand iteratorAddress , Instruction memory , int numberOfLoads
748
- ) {
749
- exists (
750
- BaseSourceVariableInstruction iteratorBase , LoadInstruction load ,
751
- ReadSideEffectInstruction read , Operand iteratorDerefAddress
752
- |
753
- numberOfLoads >= 0 and
754
- isUse ( _, iteratorAddress , iteratorBase , numberOfLoads + 1 , 0 ) and
755
- isUse ( _, iteratorDerefAddress , iteratorBase , numberOfLoads + 2 , 0 ) and
756
- iteratorBase .getResultType ( ) instanceof Interfaces:: Iterator and
757
- load .getSourceAddressOperand ( ) = iteratorDerefAddress and
758
- read .getPrimaryInstruction ( ) = load .getSourceAddress ( ) and
759
- memory = read .getSideEffectOperand ( ) .getAnyDef ( )
760
- )
761
- }
762
-
763
- /**
764
- * Holds if `iteratorDerefAddress` is an address of an iterator dereference (i.e., `*it`)
765
- * that is used for a write operation that writes the value `value` to a container that
766
- * created the iterator. `container` represents the base of the address of the container
767
- * that was used to create the iterator.
768
- */
769
- cached
770
- predicate isIteratorDef (
771
- BaseSourceVariableInstruction container , Operand iteratorDerefAddress , Node0Impl value ,
772
- int numberOfLoads , int indirectionIndex
773
- ) {
774
- exists ( Instruction memory , Instruction begin , int upper , int ind |
775
- isChiAfterIteratorDef ( memory , iteratorDerefAddress , value , numberOfLoads ) and
776
- memorySucc * ( begin , memory ) and
777
- isChiAfterBegin ( container , begin ) and
778
- upper = countIndirectionsForCppType ( getResultLanguageType ( container ) ) and
779
- ind = numberOfLoads + [ 1 .. upper ] and
780
- indirectionIndex = ind - ( numberOfLoads + 1 )
781
- )
782
- }
783
-
784
- /**
785
- * Holds if `iteratorAddress` is an address of an iterator that is used for a
786
- * read operation to read a value from a container that created the iterator.
787
- * `container` represents the base of the address of the container that was used
788
- * to create the iterator.
789
- */
790
- cached
791
- predicate isIteratorUse (
792
- BaseSourceVariableInstruction container , Operand iteratorAddress , int numberOfLoads ,
793
- int indirectionIndex
794
- ) {
795
- // Direct use
796
- exists ( Instruction begin , Instruction memory , int upper , int ind |
797
- isChiBeforeIteratorUse ( iteratorAddress , memory , numberOfLoads ) and
798
- memorySucc * ( begin , memory ) and
799
- isChiAfterBegin ( container , begin ) and
800
- upper = countIndirectionsForCppType ( getResultLanguageType ( container ) ) and
801
- ind = numberOfLoads + [ 1 .. upper ] and
802
- indirectionIndex = ind - ( numberOfLoads + 1 )
803
- )
804
- or
805
- // Use through function output
806
- exists ( Instruction memory , Instruction begin , int upper , int ind |
807
- isChiAfterIteratorArgument ( memory , iteratorAddress , numberOfLoads ) and
808
- memorySucc * ( begin , memory ) and
809
- isChiAfterBegin ( container , begin ) and
810
- upper = countIndirectionsForCppType ( getResultLanguageType ( container ) ) and
811
- ind = numberOfLoads + [ 1 .. upper ] and
812
- indirectionIndex = ind - ( numberOfLoads - 1 )
813
- )
814
- }
815
-
816
574
/** Holds if `op` is the only use of its defining instruction, and that op is used in a conversation */
817
575
private predicate isConversion ( Operand op ) {
818
576
exists ( Instruction def , Operand use |
0 commit comments