1515 */
1616
1717private import cpp
18+ private import semmle.code.cpp.models.interfaces.PointerWrapper
1819
1920/**
2021 * Holds if `f` is an instantiation of the `std::move` or `std::forward`
@@ -58,6 +59,8 @@ private predicate pointerToLvalueStep(Expr pointerIn, Expr lvalueOut) {
5859 pointerIn = lvalueOut .( ArrayExpr ) .getArrayBase ( ) .getFullyConverted ( )
5960 or
6061 pointerIn = lvalueOut .( PointerDereferenceExpr ) .getOperand ( ) .getFullyConverted ( )
62+ or
63+ pointerIn = lvalueOut .( OverloadedPointerDereferenceExpr ) .getQualifier ( ) .getFullyConverted ( )
6164}
6265
6366private predicate lvalueToPointerStep ( Expr lvalueIn , Expr pointerOut ) {
@@ -94,6 +97,12 @@ private predicate pointerToPointerStep(Expr pointerIn, Expr pointerOut) {
9497
9598private predicate lvalueToReferenceStep ( Expr lvalueIn , Expr referenceOut ) {
9699 lvalueIn .getConversion ( ) = referenceOut .( ReferenceToExpr )
100+ or
101+ exists ( PointerWrapper wrapper , Call call | call = referenceOut |
102+ referenceOut .getUnspecifiedType ( ) instanceof ReferenceType and
103+ call = wrapper .getAnUnwrapperFunction ( ) .getACallToThisFunction ( ) and
104+ lvalueIn = call .getQualifier ( ) .getFullyConverted ( )
105+ )
97106}
98107
99108private predicate referenceToLvalueStep ( Expr referenceIn , Expr lvalueOut ) {
@@ -106,6 +115,13 @@ private predicate referenceToPointerStep(Expr referenceIn, Expr pointerOut) {
106115 stdAddressOf ( call .getTarget ( ) ) and
107116 referenceIn = call .getArgument ( 0 ) .getFullyConverted ( )
108117 )
118+ or
119+ exists ( CopyConstructor copy , Call call | call = pointerOut |
120+ copy .getDeclaringType ( ) instanceof PointerWrapper and
121+ call .getTarget ( ) = copy and
122+ // The 0'th argument is the value being copied.
123+ referenceIn = call .getArgument ( 0 ) .getFullyConverted ( )
124+ )
109125}
110126
111127private predicate referenceToReferenceStep ( Expr referenceIn , Expr referenceOut ) {
@@ -190,6 +206,19 @@ private predicate pointerToUpdate(Expr pointer, Expr outer, ControlFlowNode node
190206 // See the `lvalueToUpdate` case for an explanation of this conjunct.
191207 call .getType ( ) .isDeeplyConstBelow ( )
192208 )
209+ or
210+ // Pointer wrappers behave as raw pointers for dataflow purposes.
211+ outer = call .getAnArgument ( ) .getFullyConverted ( ) and
212+ exists ( PointerWrapper wrapper | wrapper = outer .getType ( ) .stripTopLevelSpecifiers ( ) |
213+ not wrapper .pointsToConst ( )
214+ )
215+ or
216+ outer = call .getQualifier ( ) .getFullyConverted ( ) and
217+ outer .getUnspecifiedType ( ) instanceof PointerWrapper and
218+ not (
219+ call .getTarget ( ) .hasSpecifier ( "const" ) and
220+ call .getType ( ) .isDeeplyConstBelow ( )
221+ )
193222 )
194223 or
195224 exists ( PointerFieldAccess fa |
0 commit comments