@@ -59,8 +59,6 @@ private predicate pointerToLvalueStep(Expr pointerIn, Expr lvalueOut) {
5959 pointerIn = lvalueOut .( ArrayExpr ) .getArrayBase ( ) .getFullyConverted ( )
6060 or
6161 pointerIn = lvalueOut .( PointerDereferenceExpr ) .getOperand ( ) .getFullyConverted ( )
62- or
63- pointerIn = lvalueOut .( OverloadedPointerDereferenceExpr ) .getQualifier ( ) .getFullyConverted ( )
6462}
6563
6664private predicate lvalueToPointerStep ( Expr lvalueIn , Expr pointerOut ) {
@@ -69,6 +67,19 @@ private predicate lvalueToPointerStep(Expr lvalueIn, Expr pointerOut) {
6967 lvalueIn = pointerOut .( AddressOfExpr ) .getOperand ( ) .getFullyConverted ( )
7068}
7169
70+ /**
71+ * Since pointer wrappers behave as raw pointers, we treat the conversions from `lvalueToLvalueStepPure`
72+ * as pointer-to-pointer steps when they involve pointer wrappers.
73+ */
74+ private predicate pointerWrapperToPointerWrapperStep ( Expr pointerIn , Expr pointerOut ) {
75+ pointerIn .getUnspecifiedType ( ) instanceof PointerWrapper and
76+ pointerIn .getConversion ( ) = pointerOut and
77+ pointerOut .( CStyleCast ) .isImplicit ( )
78+ or
79+ pointerOut .getUnspecifiedType ( ) instanceof PointerWrapper and
80+ pointerIn .getConversion ( ) = pointerOut .( ReferenceDereferenceExpr )
81+ }
82+
7283private predicate pointerToPointerStep ( Expr pointerIn , Expr pointerOut ) {
7384 (
7485 pointerOut instanceof PointerAddExpr
@@ -93,35 +104,60 @@ private predicate pointerToPointerStep(Expr pointerIn, Expr pointerOut) {
93104 pointerIn = pointerOut .( CommaExpr ) .getRightOperand ( ) .getFullyConverted ( )
94105 or
95106 pointerIn = pointerOut .( StmtExpr ) .getResultExpr ( ) .getFullyConverted ( )
107+ or
108+ pointerWrapperToPointerWrapperStep ( pointerIn , pointerOut )
96109}
97110
98111private predicate lvalueToReferenceStep ( Expr lvalueIn , Expr referenceOut ) {
99112 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- )
106113}
107114
108115private predicate referenceToLvalueStep ( Expr referenceIn , Expr lvalueOut ) {
109116 referenceIn .getConversion ( ) = lvalueOut .( ReferenceDereferenceExpr )
110117}
111118
119+ private predicate referenceToPointerToPointerStep ( Expr referenceToPointerIn , Expr pointerOut ) {
120+ exists ( CopyConstructor copy , Call call | call = pointerOut |
121+ copy .getDeclaringType ( ) instanceof PointerWrapper and
122+ call .getTarget ( ) = copy and
123+ // The 0'th argument is the value being copied.
124+ referenceToPointerIn = call .getArgument ( 0 ) .getFullyConverted ( )
125+ )
126+ or
127+ referenceToPointerIn .getConversion ( ) = pointerOut .( ReferenceDereferenceExpr )
128+ }
129+
130+ /**
131+ * This predicate exists only to support "fake pointer" objects like
132+ * smart pointers. We treat these as raw pointers for dataflow purposes.
133+ */
134+ private predicate referenceToPointerToUpdate (
135+ Expr referenceToPointer , Expr outer , ControlFlowNode node
136+ ) {
137+ exists ( Call call |
138+ node = call and
139+ outer = call .getAnArgument ( ) .getFullyConverted ( ) and
140+ not stdIdentityFunction ( call .getTarget ( ) ) and
141+ not stdAddressOf ( call .getTarget ( ) ) and
142+ exists ( ReferenceType rt | rt = outer .getType ( ) .stripTopLevelSpecifiers ( ) |
143+ rt .getBaseType ( ) .getUnspecifiedType ( ) =
144+ any ( PointerWrapper wrapper | not wrapper .pointsToConst ( ) )
145+ )
146+ ) and
147+ referenceToPointer = outer
148+ or
149+ exists ( Expr pointerMid |
150+ referenceToPointerToPointerStep ( referenceToPointer , pointerMid ) and
151+ pointerToUpdate ( pointerMid , outer , node )
152+ )
153+ }
154+
112155private predicate referenceToPointerStep ( Expr referenceIn , Expr pointerOut ) {
113156 pointerOut =
114157 any ( FunctionCall call |
115158 stdAddressOf ( call .getTarget ( ) ) and
116159 referenceIn = call .getArgument ( 0 ) .getFullyConverted ( )
117160 )
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- )
125161}
126162
127163private predicate referenceToReferenceStep ( Expr referenceIn , Expr referenceOut ) {
@@ -238,6 +274,16 @@ private predicate pointerToUpdate(Expr pointer, Expr outer, ControlFlowNode node
238274 pointerToPointerStep ( pointer , pointerMid ) and
239275 pointerToUpdate ( pointerMid , outer , node )
240276 )
277+ or
278+ exists ( Expr referenceMid |
279+ pointerToReferenceStep ( pointer , referenceMid ) and
280+ referenceToUpdate ( referenceMid , outer , node )
281+ )
282+ or
283+ exists ( Expr referenceToPointerMid |
284+ pointerToReferenceToPointerStep ( pointer , referenceToPointerMid ) and
285+ referenceToPointerToUpdate ( referenceToPointerMid , outer , node )
286+ )
241287}
242288
243289private predicate referenceToUpdate ( Expr reference , Expr outer , ControlFlowNode node ) {
@@ -247,9 +293,7 @@ private predicate referenceToUpdate(Expr reference, Expr outer, ControlFlowNode
247293 not stdIdentityFunction ( call .getTarget ( ) ) and
248294 not stdAddressOf ( call .getTarget ( ) ) and
249295 exists ( ReferenceType rt | rt = outer .getType ( ) .stripTopLevelSpecifiers ( ) |
250- not rt .getBaseType ( ) .isConst ( ) or
251- rt .getBaseType ( ) .getUnspecifiedType ( ) =
252- any ( PointerWrapper wrapper | not wrapper .pointsToConst ( ) )
296+ not rt .getBaseType ( ) .isConst ( )
253297 )
254298 ) and
255299 reference = outer
@@ -270,6 +314,14 @@ private predicate referenceToUpdate(Expr reference, Expr outer, ControlFlowNode
270314 )
271315}
272316
317+ private predicate pointerToReferenceStep ( Expr pointerIn , Expr referenceOut ) {
318+ exists ( PointerWrapper wrapper , Call call | call = referenceOut |
319+ referenceOut .getUnspecifiedType ( ) instanceof ReferenceType and
320+ call = wrapper .getAnUnwrapperFunction ( ) .getACallToThisFunction ( ) and
321+ pointerIn = call .getQualifier ( ) .getFullyConverted ( )
322+ )
323+ }
324+
273325private predicate lvalueFromVariableAccess ( VariableAccess va , Expr lvalue ) {
274326 // Base case for non-reference types.
275327 lvalue = va and
@@ -331,6 +383,21 @@ private predicate referenceFromVariableAccess(VariableAccess va, Expr reference)
331383 lvalueFromVariableAccess ( va , prev ) and
332384 lvalueToReferenceStep ( prev , reference )
333385 )
386+ or
387+ exists ( Expr prev |
388+ pointerFromVariableAccess ( va , prev ) and
389+ pointerToReferenceStep ( prev , reference )
390+ )
391+ }
392+
393+ private predicate pointerToReferenceToPointerStep ( Expr pointerIn , Expr referenceToPointerOut ) {
394+ pointerIn .getConversion ( ) = referenceToPointerOut .( ReferenceToExpr )
395+ or
396+ exists ( PointerWrapper wrapper , Call call | call = referenceToPointerOut |
397+ referenceToPointerOut .getUnspecifiedType ( ) instanceof ReferenceType and
398+ call = wrapper .getAnUnwrapperFunction ( ) .getACallToThisFunction ( ) and
399+ pointerIn = call .getQualifier ( ) .getFullyConverted ( )
400+ )
334401}
335402
336403/**
@@ -351,6 +418,8 @@ predicate valueToUpdate(Expr inner, Expr outer, ControlFlowNode node) {
351418 pointerToUpdate ( inner , outer , node )
352419 or
353420 referenceToUpdate ( inner , outer , node )
421+ or
422+ referenceToPointerToUpdate ( inner , outer , node )
354423 ) and
355424 (
356425 inner instanceof VariableAccess and
0 commit comments