@@ -123,14 +123,34 @@ class IteratorCrementNonMemberOperator extends Operator {
123123}
124124
125125private class IteratorCrementNonMemberOperatorModel extends IteratorCrementNonMemberOperator ,
126- DataFlowFunction
126+ DataFlowFunction , SideEffectFunction , AliasFunction
127127{
128128 override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
129129 input = getIteratorArgumentInput ( this , 0 ) and
130130 output .isReturnValue ( )
131131 or
132132 input .isParameterDeref ( 0 ) and output .isReturnValueDeref ( )
133133 }
134+
135+ override predicate hasOnlySpecificReadSideEffects ( ) { any ( ) }
136+
137+ override predicate hasOnlySpecificWriteSideEffects ( ) { any ( ) }
138+
139+ override predicate hasSpecificReadSideEffect ( ParameterIndex i , boolean buffer ) {
140+ i = 0 and buffer = false
141+ }
142+
143+ override predicate hasSpecificWriteSideEffect ( ParameterIndex i , boolean buffer , boolean mustWrite ) {
144+ // `buffer` must be `true` or `mustWrite` must be `false` to ensure that
145+ // the IR alias analysis doesn't think that `it++` doesn't completely override
146+ // the value of the iterator. Ideally, the IR alias analysis shouldn't deal with
147+ // iterators, but this is necessary for taintflow to get any results in our iterator tests.
148+ i = 0 and buffer = false and mustWrite = false
149+ }
150+
151+ override predicate parameterNeverEscapes ( int index ) { none ( ) }
152+
153+ override predicate parameterEscapesOnlyViaReturn ( int index ) { index = 0 }
134154}
135155
136156/**
@@ -146,7 +166,7 @@ class IteratorCrementMemberOperator extends MemberFunction {
146166}
147167
148168private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOperator ,
149- DataFlowFunction , TaintFunction
169+ DataFlowFunction , TaintFunction , SideEffectFunction , AliasFunction
150170{
151171 override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
152172 input .isQualifierAddress ( ) and
@@ -163,6 +183,26 @@ private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOp
163183 input .isQualifierObject ( ) and
164184 output .isReturnValueDeref ( )
165185 }
186+
187+ override predicate hasOnlySpecificReadSideEffects ( ) { any ( ) }
188+
189+ override predicate hasOnlySpecificWriteSideEffects ( ) { any ( ) }
190+
191+ override predicate hasSpecificReadSideEffect ( ParameterIndex i , boolean buffer ) {
192+ i = - 1 and buffer = false
193+ }
194+
195+ override predicate hasSpecificWriteSideEffect ( ParameterIndex i , boolean buffer , boolean mustWrite ) {
196+ // `buffer` must be `true` or `mustWrite` must be `false` to ensure that
197+ // the IR alias analysis doesn't think that `it++` doesn't completely override
198+ // the value of the iterator. Ideally, the IR alias analysis shouldn't deal with
199+ // iterators, but this is necessary for taintflow to get any results in our iterator tests.
200+ i = - 1 and buffer = false and mustWrite = false
201+ }
202+
203+ override predicate parameterNeverEscapes ( int index ) { index = - 1 }
204+
205+ override predicate parameterEscapesOnlyViaReturn ( int index ) { none ( ) }
166206}
167207
168208/**
@@ -332,7 +372,7 @@ class IteratorAssignArithmeticOperator extends Function {
332372 * non-member and member versions, use `IteratorPointerDereferenceOperator`.
333373 */
334374class IteratorPointerDereferenceMemberOperator extends MemberFunction , TaintFunction ,
335- IteratorReferenceFunction
375+ IteratorReferenceFunction , AliasFunction , SideEffectFunction
336376{
337377 IteratorPointerDereferenceMemberOperator ( ) {
338378 this .getClassAndName ( "operator*" ) instanceof Iterator
@@ -345,6 +385,18 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc
345385 input .isReturnValueDeref ( ) and
346386 output .isQualifierObject ( )
347387 }
388+
389+ override predicate parameterNeverEscapes ( int index ) { index = - 1 }
390+
391+ override predicate parameterEscapesOnlyViaReturn ( int index ) { none ( ) }
392+
393+ override predicate hasOnlySpecificReadSideEffects ( ) { any ( ) }
394+
395+ override predicate hasOnlySpecificWriteSideEffects ( ) { any ( ) }
396+
397+ override predicate hasSpecificReadSideEffect ( ParameterIndex i , boolean buffer ) {
398+ i = - 1 and buffer = false
399+ }
348400}
349401
350402/**
@@ -361,7 +413,7 @@ class IteratorPointerDereferenceNonMemberOperator extends Operator, IteratorRefe
361413}
362414
363415private class IteratorPointerDereferenceNonMemberOperatorModel extends IteratorPointerDereferenceNonMemberOperator ,
364- TaintFunction
416+ TaintFunction , AliasFunction , SideEffectFunction
365417{
366418 override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
367419 input = getIteratorArgumentInput ( this , 0 ) and
@@ -370,6 +422,18 @@ private class IteratorPointerDereferenceNonMemberOperatorModel extends IteratorP
370422 input .isReturnValueDeref ( ) and
371423 output .isParameterDeref ( 0 )
372424 }
425+
426+ override predicate parameterNeverEscapes ( int index ) { index = 0 }
427+
428+ override predicate parameterEscapesOnlyViaReturn ( int index ) { none ( ) }
429+
430+ override predicate hasOnlySpecificReadSideEffects ( ) { any ( ) }
431+
432+ override predicate hasOnlySpecificWriteSideEffects ( ) { any ( ) }
433+
434+ override predicate hasSpecificReadSideEffect ( ParameterIndex i , boolean buffer ) {
435+ i = 0 and buffer = false
436+ }
373437}
374438
375439/**
@@ -420,6 +484,71 @@ class IteratorAssignmentMemberOperator extends MemberFunction {
420484 }
421485}
422486
487+ /**
488+ * A member `operator==` or `operator!=` function for an iterator type.
489+ *
490+ * Note that this class _only_ matches member functions. To find both
491+ * non-member and member versions, use `IteratorLogicalOperator`.
492+ */
493+ class IteratorLogicalMemberOperator extends MemberFunction {
494+ IteratorLogicalMemberOperator ( ) {
495+ this .getClassAndName ( [ "operator!=" , "operator==" ] ) instanceof Iterator
496+ }
497+ }
498+
499+ private class IteratorLogicalMemberOperatorModel extends IteratorLogicalMemberOperator ,
500+ AliasFunction , SideEffectFunction
501+ {
502+ override predicate parameterNeverEscapes ( int index ) { index = [ - 1 , 0 ] }
503+
504+ override predicate parameterEscapesOnlyViaReturn ( int index ) { none ( ) }
505+
506+ override predicate hasOnlySpecificReadSideEffects ( ) { any ( ) }
507+
508+ override predicate hasOnlySpecificWriteSideEffects ( ) { any ( ) }
509+
510+ override predicate hasSpecificReadSideEffect ( ParameterIndex i , boolean buffer ) {
511+ i = - 1 and buffer = false
512+ }
513+ }
514+
515+ /**
516+ * A member `operator==` or `operator!=` function for an iterator type.
517+ *
518+ * Note that this class _only_ matches non-member functions. To find both
519+ * non-member and member versions, use `IteratorLogicalOperator`.
520+ */
521+ class IteratorLogicalNonMemberOperator extends Function {
522+ IteratorLogicalNonMemberOperator ( ) {
523+ this .hasName ( [ "operator!=" , "operator==" ] ) and
524+ exists ( getIteratorArgumentInput ( this , 0 ) ) and
525+ exists ( getIteratorArgumentInput ( this , 1 ) )
526+ }
527+ }
528+
529+ private class IteratorLogicalNonMemberOperatorModel extends IteratorLogicalNonMemberOperator ,
530+ AliasFunction , SideEffectFunction
531+ {
532+ override predicate parameterNeverEscapes ( int index ) { index = [ 0 , 1 ] }
533+
534+ override predicate parameterEscapesOnlyViaReturn ( int index ) { none ( ) }
535+
536+ override predicate hasOnlySpecificReadSideEffects ( ) { any ( ) }
537+
538+ override predicate hasOnlySpecificWriteSideEffects ( ) { any ( ) }
539+ }
540+
541+ /**
542+ * A (member or non-member) `operator==` or `operator!=` function for an iterator type.
543+ */
544+ class IteratorLogicalOperator extends Function {
545+ IteratorLogicalOperator ( ) {
546+ this instanceof IteratorLogicalNonMemberOperator
547+ or
548+ this instanceof IteratorLogicalMemberOperator
549+ }
550+ }
551+
423552/**
424553 * An `operator=` member function of an iterator class that is not a copy or move assignment
425554 * operator.
@@ -428,12 +557,24 @@ class IteratorAssignmentMemberOperator extends MemberFunction {
428557 * `operator*` and use their own `operator=` to assign to the container.
429558 */
430559private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMemberOperator ,
431- TaintFunction
560+ TaintFunction , SideEffectFunction , AliasFunction
432561{
433562 override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
434563 input .isParameterDeref ( 0 ) and
435564 output .isQualifierObject ( )
436565 }
566+
567+ override predicate hasOnlySpecificReadSideEffects ( ) { any ( ) }
568+
569+ override predicate hasOnlySpecificWriteSideEffects ( ) { any ( ) }
570+
571+ override predicate hasSpecificWriteSideEffect ( ParameterIndex i , boolean buffer , boolean mustWrite ) {
572+ i = - 1 and buffer = false and mustWrite = false
573+ }
574+
575+ override predicate parameterNeverEscapes ( int index ) { index = 0 }
576+
577+ override predicate parameterEscapesOnlyViaReturn ( int index ) { index = - 1 }
437578}
438579
439580/**
0 commit comments