@@ -123,14 +123,34 @@ class IteratorCrementNonMemberOperator extends Operator {
123
123
}
124
124
125
125
private class IteratorCrementNonMemberOperatorModel extends IteratorCrementNonMemberOperator ,
126
- DataFlowFunction
126
+ DataFlowFunction , SideEffectFunction , AliasFunction
127
127
{
128
128
override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
129
129
input = getIteratorArgumentInput ( this , 0 ) and
130
130
output .isReturnValue ( )
131
131
or
132
132
input .isParameterDeref ( 0 ) and output .isReturnValueDeref ( )
133
133
}
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 }
134
154
}
135
155
136
156
/**
@@ -146,7 +166,7 @@ class IteratorCrementMemberOperator extends MemberFunction {
146
166
}
147
167
148
168
private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOperator ,
149
- DataFlowFunction , TaintFunction
169
+ DataFlowFunction , TaintFunction , SideEffectFunction , AliasFunction
150
170
{
151
171
override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
152
172
input .isQualifierAddress ( ) and
@@ -163,6 +183,26 @@ private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOp
163
183
input .isQualifierObject ( ) and
164
184
output .isReturnValueDeref ( )
165
185
}
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 ( ) }
166
206
}
167
207
168
208
/**
@@ -332,7 +372,7 @@ class IteratorAssignArithmeticOperator extends Function {
332
372
* non-member and member versions, use `IteratorPointerDereferenceOperator`.
333
373
*/
334
374
class IteratorPointerDereferenceMemberOperator extends MemberFunction , TaintFunction ,
335
- IteratorReferenceFunction
375
+ IteratorReferenceFunction , AliasFunction , SideEffectFunction
336
376
{
337
377
IteratorPointerDereferenceMemberOperator ( ) {
338
378
this .getClassAndName ( "operator*" ) instanceof Iterator
@@ -345,6 +385,18 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc
345
385
input .isReturnValueDeref ( ) and
346
386
output .isQualifierObject ( )
347
387
}
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
+ }
348
400
}
349
401
350
402
/**
@@ -361,7 +413,7 @@ class IteratorPointerDereferenceNonMemberOperator extends Operator, IteratorRefe
361
413
}
362
414
363
415
private class IteratorPointerDereferenceNonMemberOperatorModel extends IteratorPointerDereferenceNonMemberOperator ,
364
- TaintFunction
416
+ TaintFunction , AliasFunction , SideEffectFunction
365
417
{
366
418
override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
367
419
input = getIteratorArgumentInput ( this , 0 ) and
@@ -370,6 +422,18 @@ private class IteratorPointerDereferenceNonMemberOperatorModel extends IteratorP
370
422
input .isReturnValueDeref ( ) and
371
423
output .isParameterDeref ( 0 )
372
424
}
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
+ }
373
437
}
374
438
375
439
/**
@@ -420,6 +484,71 @@ class IteratorAssignmentMemberOperator extends MemberFunction {
420
484
}
421
485
}
422
486
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
+
423
552
/**
424
553
* An `operator=` member function of an iterator class that is not a copy or move assignment
425
554
* operator.
@@ -428,12 +557,24 @@ class IteratorAssignmentMemberOperator extends MemberFunction {
428
557
* `operator*` and use their own `operator=` to assign to the container.
429
558
*/
430
559
private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMemberOperator ,
431
- TaintFunction
560
+ TaintFunction , SideEffectFunction , AliasFunction
432
561
{
433
562
override predicate hasTaintFlow ( FunctionInput input , FunctionOutput output ) {
434
563
input .isParameterDeref ( 0 ) and
435
564
output .isQualifierObject ( )
436
565
}
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 }
437
578
}
438
579
439
580
/**
0 commit comments