@@ -59,8 +59,6 @@ private predicate pointerToLvalueStep(Expr pointerIn, Expr lvalueOut) {
59
59
pointerIn = lvalueOut .( ArrayExpr ) .getArrayBase ( ) .getFullyConverted ( )
60
60
or
61
61
pointerIn = lvalueOut .( PointerDereferenceExpr ) .getOperand ( ) .getFullyConverted ( )
62
- or
63
- pointerIn = lvalueOut .( OverloadedPointerDereferenceExpr ) .getQualifier ( ) .getFullyConverted ( )
64
62
}
65
63
66
64
private predicate lvalueToPointerStep ( Expr lvalueIn , Expr pointerOut ) {
@@ -69,6 +67,19 @@ private predicate lvalueToPointerStep(Expr lvalueIn, Expr pointerOut) {
69
67
lvalueIn = pointerOut .( AddressOfExpr ) .getOperand ( ) .getFullyConverted ( )
70
68
}
71
69
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
+
72
83
private predicate pointerToPointerStep ( Expr pointerIn , Expr pointerOut ) {
73
84
(
74
85
pointerOut instanceof PointerAddExpr
@@ -93,35 +104,60 @@ private predicate pointerToPointerStep(Expr pointerIn, Expr pointerOut) {
93
104
pointerIn = pointerOut .( CommaExpr ) .getRightOperand ( ) .getFullyConverted ( )
94
105
or
95
106
pointerIn = pointerOut .( StmtExpr ) .getResultExpr ( ) .getFullyConverted ( )
107
+ or
108
+ pointerWrapperToPointerWrapperStep ( pointerIn , pointerOut )
96
109
}
97
110
98
111
private predicate lvalueToReferenceStep ( Expr lvalueIn , Expr referenceOut ) {
99
112
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
- )
106
113
}
107
114
108
115
private predicate referenceToLvalueStep ( Expr referenceIn , Expr lvalueOut ) {
109
116
referenceIn .getConversion ( ) = lvalueOut .( ReferenceDereferenceExpr )
110
117
}
111
118
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
+
112
155
private predicate referenceToPointerStep ( Expr referenceIn , Expr pointerOut ) {
113
156
pointerOut =
114
157
any ( FunctionCall call |
115
158
stdAddressOf ( call .getTarget ( ) ) and
116
159
referenceIn = call .getArgument ( 0 ) .getFullyConverted ( )
117
160
)
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
- )
125
161
}
126
162
127
163
private predicate referenceToReferenceStep ( Expr referenceIn , Expr referenceOut ) {
@@ -238,6 +274,16 @@ private predicate pointerToUpdate(Expr pointer, Expr outer, ControlFlowNode node
238
274
pointerToPointerStep ( pointer , pointerMid ) and
239
275
pointerToUpdate ( pointerMid , outer , node )
240
276
)
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
+ )
241
287
}
242
288
243
289
private predicate referenceToUpdate ( Expr reference , Expr outer , ControlFlowNode node ) {
@@ -247,9 +293,7 @@ private predicate referenceToUpdate(Expr reference, Expr outer, ControlFlowNode
247
293
not stdIdentityFunction ( call .getTarget ( ) ) and
248
294
not stdAddressOf ( call .getTarget ( ) ) and
249
295
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 ( )
253
297
)
254
298
) and
255
299
reference = outer
@@ -270,6 +314,14 @@ private predicate referenceToUpdate(Expr reference, Expr outer, ControlFlowNode
270
314
)
271
315
}
272
316
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
+
273
325
private predicate lvalueFromVariableAccess ( VariableAccess va , Expr lvalue ) {
274
326
// Base case for non-reference types.
275
327
lvalue = va and
@@ -331,6 +383,21 @@ private predicate referenceFromVariableAccess(VariableAccess va, Expr reference)
331
383
lvalueFromVariableAccess ( va , prev ) and
332
384
lvalueToReferenceStep ( prev , reference )
333
385
)
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
+ )
334
401
}
335
402
336
403
/**
@@ -351,6 +418,8 @@ predicate valueToUpdate(Expr inner, Expr outer, ControlFlowNode node) {
351
418
pointerToUpdate ( inner , outer , node )
352
419
or
353
420
referenceToUpdate ( inner , outer , node )
421
+ or
422
+ referenceToPointerToUpdate ( inner , outer , node )
354
423
) and
355
424
(
356
425
inner instanceof VariableAccess and
0 commit comments