11import semmle.code.cpp.models.interfaces.DataFlow
22import semmle.code.cpp.models.interfaces.Taint
33import semmle.code.cpp.models.interfaces.Alias
4+ import semmle.code.cpp.models.interfaces.FlowOutBarrier
45
56/**
67 * The standard function `swap`. A use of `swap` looks like this:
78 * ```
89 * std::swap(obj1, obj2)
910 * ```
1011 */
11- private class Swap extends DataFlowFunction {
12+ private class Swap extends DataFlowFunction , FlowOutBarrierFunction {
1213 Swap ( ) { this .hasQualifiedName ( [ "std" , "bsl" ] , "swap" ) }
1314
1415 override predicate hasDataFlow ( FunctionInput input , FunctionOutput output ) {
@@ -18,6 +19,8 @@ private class Swap extends DataFlowFunction {
1819 input .isParameterDeref ( 1 ) and
1920 output .isParameterDeref ( 0 )
2021 }
22+
23+ override predicate isFlowOutBarrier ( FunctionInput input ) { input .isParameterDeref ( 1 ) }
2124}
2225
2326/**
@@ -26,7 +29,9 @@ private class Swap extends DataFlowFunction {
2629 * obj1.swap(obj2)
2730 * ```
2831 */
29- private class MemberSwap extends TaintFunction , MemberFunction , AliasFunction {
32+ private class MemberSwap extends TaintFunction , MemberFunction , AliasFunction ,
33+ FlowOutBarrierFunction
34+ {
3035 MemberSwap ( ) {
3136 this .hasName ( "swap" ) and
3237 this .getNumberOfParameters ( ) = 1 and
@@ -47,4 +52,8 @@ private class MemberSwap extends TaintFunction, MemberFunction, AliasFunction {
4752 override predicate parameterEscapesOnlyViaReturn ( int index ) { index = 0 }
4853
4954 override predicate parameterIsAlwaysReturned ( int index ) { index = 0 }
55+
56+ override predicate isFlowOutBarrier ( FunctionInput input ) {
57+ input .isQualifierObject ( ) or input .isParameterDeref ( 0 )
58+ }
5059}
0 commit comments