1
1
import semmle.code.cpp.models.interfaces.DataFlow
2
2
import semmle.code.cpp.models.interfaces.Taint
3
3
import semmle.code.cpp.models.interfaces.Alias
4
+ import semmle.code.cpp.models.interfaces.FlowOutBarrier
4
5
5
6
/**
6
7
* The standard function `swap`. A use of `swap` looks like this:
7
8
* ```
8
9
* std::swap(obj1, obj2)
9
10
* ```
10
11
*/
11
- private class Swap extends DataFlowFunction {
12
+ private class Swap extends DataFlowFunction , FlowOutBarrierFunction {
12
13
Swap ( ) { this .hasQualifiedName ( [ "std" , "bsl" ] , "swap" ) }
13
14
14
15
override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
@@ -18,6 +19,8 @@ private class Swap extends DataFlowFunction {
18
19
input .isParameterDeref ( 1 ) and
19
20
output .isParameterDeref ( 0 )
20
21
}
22
+
23
+ override predicate isFlowOutBarrier ( FunctionInput input ) { input .isParameterDeref ( 1 ) }
21
24
}
22
25
23
26
/**
@@ -26,7 +29,9 @@ private class Swap extends DataFlowFunction {
26
29
* obj1.swap(obj2)
27
30
* ```
28
31
*/
29
- private class MemberSwap extends TaintFunction , MemberFunction , AliasFunction {
32
+ private class MemberSwap extends TaintFunction , MemberFunction , AliasFunction ,
33
+ FlowOutBarrierFunction
34
+ {
30
35
MemberSwap ( ) {
31
36
this .hasName ( "swap" ) and
32
37
this .getNumberOfParameters ( ) = 1 and
@@ -47,4 +52,8 @@ private class MemberSwap extends TaintFunction, MemberFunction, AliasFunction {
47
52
override predicate parameterEscapesOnlyViaReturn ( int index ) { index = 0 }
48
53
49
54
override predicate parameterIsAlwaysReturned ( int index ) { index = 0 }
55
+
56
+ override predicate isFlowOutBarrier ( FunctionInput input ) {
57
+ input .isQualifierObject ( ) or input .isParameterDeref ( 0 )
58
+ }
50
59
}
0 commit comments