@@ -123,14 +123,32 @@ 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
+ // See the comment on `IteratorCrementMemberOperatorModel::hasSpecificWriteSideEffect`
145
+ // for an explanation of these values.
146
+ i = 0 and buffer = false and mustWrite = false
147
+ }
148
+
149
+ override predicate parameterNeverEscapes ( int index ) { none ( ) }
150
+
151
+ override predicate parameterEscapesOnlyViaReturn ( int index ) { index = 0 }
134
152
}
135
153
136
154
/**
@@ -146,7 +164,7 @@ class IteratorCrementMemberOperator extends MemberFunction {
146
164
}
147
165
148
166
private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOperator ,
149
- DataFlowFunction , TaintFunction
167
+ DataFlowFunction , TaintFunction , SideEffectFunction , AliasFunction
150
168
{
151
169
override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
152
170
input .isQualifierAddress ( ) and
@@ -163,6 +181,28 @@ private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOp
163
181
input .isQualifierObject ( ) and
164
182
output .isReturnValueDeref ( )
165
183
}
184
+
185
+ override predicate hasOnlySpecificReadSideEffects ( ) { any ( ) }
186
+
187
+ override predicate hasOnlySpecificWriteSideEffects ( ) { any ( ) }
188
+
189
+ override predicate hasSpecificReadSideEffect ( ParameterIndex i , boolean buffer ) {
190
+ i = - 1 and buffer = false
191
+ }
192
+
193
+ override predicate hasSpecificWriteSideEffect ( ParameterIndex i , boolean buffer , boolean mustWrite ) {
194
+ // We have two choices here: either `buffer` must be `true` or `mustWrite`
195
+ // must be `false` to ensure that the IR alias analysis doesn't think that
196
+ // `it++` completely override the value of the iterator.
197
+ // We choose `mustWrite` must be `false`. In that case, the value of
198
+ // `buffer` isn't super important (it just decides which kind of read side
199
+ // effect will be emitted).
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,26 @@ 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
+ // See the comment on `IteratorCrementMemberOperatorModel::hasSpecificWriteSideEffect`
573
+ // for an explanation of these values.
574
+ i = - 1 and buffer = false and mustWrite = false
575
+ }
576
+
577
+ override predicate parameterNeverEscapes ( int index ) { index = 0 }
578
+
579
+ override predicate parameterEscapesOnlyViaReturn ( int index ) { index = - 1 }
437
580
}
438
581
439
582
/**
0 commit comments