@@ -206,7 +206,34 @@ private predicate deconstructSizeExpr(Expr sizeExpr, Expr lengthExpr, int sizeof
206
206
}
207
207
208
208
/** A `Function` that is a call target of an allocation. */
209
- private signature class CallAllocationExprTarget extends Function ;
209
+ private signature class CallAllocationExprTarget extends Function {
210
+ /**
211
+ * Gets the index of the input pointer argument to be reallocated, if
212
+ * this is a `realloc` function.
213
+ */
214
+ int getReallocPtrArg ( ) ;
215
+
216
+ /**
217
+ * Gets the index of the argument for the allocation size, if any. The actual
218
+ * allocation size is the value of this argument multiplied by the result of
219
+ * `getSizeMult()`, in bytes.
220
+ */
221
+ int getSizeArg ( ) ;
222
+
223
+ /**
224
+ * Gets the index of an argument that multiplies the allocation size given
225
+ * by `getSizeArg`, if any.
226
+ */
227
+ int getSizeMult ( ) ;
228
+
229
+ /**
230
+ * Holds if this allocation requires a
231
+ * corresponding deallocation of some sort (most do, but `alloca` for example
232
+ * does not). If it is unclear, we default to no (for example a placement `new`
233
+ * allocation may or may not require a corresponding `delete`).
234
+ */
235
+ predicate requiresDealloc ( ) ;
236
+ }
210
237
211
238
/**
212
239
* This module abstracts over the type of allocation call-targets and provides a
@@ -220,118 +247,68 @@ private signature class CallAllocationExprTarget extends Function;
220
247
* function using various heuristics.
221
248
*/
222
249
private module CallAllocationExprBase< CallAllocationExprTarget Target> {
223
- /** A module that contains the collection of member-predicates required on `Target`. */
224
- signature module Param {
225
- /**
226
- * Gets the index of the input pointer argument to be reallocated, if
227
- * this is a `realloc` function.
228
- */
229
- int getReallocPtrArg ( Target target ) ;
230
-
231
- /**
232
- * Gets the index of the argument for the allocation size, if any. The actual
233
- * allocation size is the value of this argument multiplied by the result of
234
- * `getSizeMult()`, in bytes.
235
- */
236
- int getSizeArg ( Target target ) ;
237
-
238
- /**
239
- * Gets the index of an argument that multiplies the allocation size given
240
- * by `getSizeArg`, if any.
241
- */
242
- int getSizeMult ( Target target ) ;
243
-
244
- /**
245
- * Holds if this allocation requires a
246
- * corresponding deallocation of some sort (most do, but `alloca` for example
247
- * does not). If it is unclear, we default to no (for example a placement `new`
248
- * allocation may or may not require a corresponding `delete`).
249
- */
250
- predicate requiresDealloc ( Target target ) ;
251
- }
252
-
253
250
/**
254
- * A module that abstracts over a collection of predicates in
255
- * the `Param` module). This should really be member-predicates
256
- * on `CallAllocationExprTarget`, but we cannot yet write this in QL.
251
+ * An allocation expression that is a function call, such as call to `malloc`.
257
252
*/
258
- module With< Param P> {
259
- private import P
260
-
261
- /**
262
- * An allocation expression that is a function call, such as call to `malloc`.
263
- */
264
- class CallAllocationExprImpl instanceof FunctionCall {
265
- Target target ;
266
-
267
- CallAllocationExprImpl ( ) {
268
- target = this .getTarget ( ) and
269
- // realloc(ptr, 0) only frees the pointer
270
- not (
271
- exists ( getReallocPtrArg ( target ) ) and
272
- this .getArgument ( getSizeArg ( target ) ) .getValue ( ) .toInt ( ) = 0
273
- ) and
274
- // these are modeled directly (and more accurately), avoid duplication
275
- not exists ( NewOrNewArrayExpr new | new .getAllocatorCall ( ) = this )
276
- }
277
-
278
- string toString ( ) { result = super .toString ( ) }
279
-
280
- Expr getSizeExprImpl ( ) {
281
- exists ( Expr sizeExpr | sizeExpr = super .getArgument ( getSizeArg ( target ) ) |
282
- if exists ( getSizeMult ( target ) )
283
- then result = sizeExpr
284
- else
285
- exists ( Expr lengthExpr |
286
- deconstructSizeExpr ( sizeExpr , lengthExpr , _) and
287
- result = lengthExpr
288
- )
289
- )
290
- }
291
-
292
- int getSizeMultImpl ( ) {
293
- // malloc with multiplier argument that is a constant
294
- result = super .getArgument ( getSizeMult ( target ) ) .getValue ( ) .toInt ( )
295
- or
296
- // malloc with no multiplier argument
297
- not exists ( getSizeMult ( target ) ) and
298
- deconstructSizeExpr ( super .getArgument ( getSizeArg ( target ) ) , _, result )
299
- }
300
-
301
- int getSizeBytesImpl ( ) {
302
- result = this .getSizeExprImpl ( ) .getValue ( ) .toInt ( ) * this .getSizeMultImpl ( )
303
- }
304
-
305
- Expr getReallocPtrImpl ( ) { result = super .getArgument ( getReallocPtrArg ( target ) ) }
306
-
307
- Type getAllocatedElementTypeImpl ( ) {
308
- result =
309
- super .getFullyConverted ( ) .getType ( ) .stripTopLevelSpecifiers ( ) .( PointerType ) .getBaseType ( ) and
310
- not result instanceof VoidType
311
- }
312
-
313
- predicate requiresDeallocImpl ( ) { requiresDealloc ( target ) }
253
+ class CallAllocationExprImpl instanceof FunctionCall {
254
+ Target target ;
255
+
256
+ CallAllocationExprImpl ( ) {
257
+ target = this .getTarget ( ) and
258
+ // realloc(ptr, 0) only frees the pointer
259
+ not (
260
+ exists ( target .getReallocPtrArg ( ) ) and
261
+ this .getArgument ( target .getSizeArg ( ) ) .getValue ( ) .toInt ( ) = 0
262
+ ) and
263
+ // these are modeled directly (and more accurately), avoid duplication
264
+ not exists ( NewOrNewArrayExpr new | new .getAllocatorCall ( ) = this )
314
265
}
315
- }
316
- }
317
266
318
- private module CallAllocationExpr {
319
- private module Param implements CallAllocationExprBase< AllocationFunction > :: Param {
320
- int getReallocPtrArg ( AllocationFunction f ) { result = f .getReallocPtrArg ( ) }
267
+ string toString ( ) { result = super .toString ( ) }
268
+
269
+ Expr getSizeExprImpl ( ) {
270
+ exists ( Expr sizeExpr | sizeExpr = super .getArgument ( target .getSizeArg ( ) ) |
271
+ if exists ( target .getSizeMult ( ) )
272
+ then result = sizeExpr
273
+ else
274
+ exists ( Expr lengthExpr |
275
+ deconstructSizeExpr ( sizeExpr , lengthExpr , _) and
276
+ result = lengthExpr
277
+ )
278
+ )
279
+ }
280
+
281
+ int getSizeMultImpl ( ) {
282
+ // malloc with multiplier argument that is a constant
283
+ result = super .getArgument ( target .getSizeMult ( ) ) .getValue ( ) .toInt ( )
284
+ or
285
+ // malloc with no multiplier argument
286
+ not exists ( target .getSizeMult ( ) ) and
287
+ deconstructSizeExpr ( super .getArgument ( target .getSizeArg ( ) ) , _, result )
288
+ }
289
+
290
+ int getSizeBytesImpl ( ) {
291
+ result = this .getSizeExprImpl ( ) .getValue ( ) .toInt ( ) * this .getSizeMultImpl ( )
292
+ }
321
293
322
- int getSizeArg ( AllocationFunction f ) { result = f . getSizeArg ( ) }
294
+ Expr getReallocPtrImpl ( ) { result = super . getArgument ( target . getReallocPtrArg ( ) ) }
323
295
324
- int getSizeMult ( AllocationFunction f ) { result = f .getSizeMult ( ) }
296
+ Type getAllocatedElementTypeImpl ( ) {
297
+ result =
298
+ super .getFullyConverted ( ) .getType ( ) .stripTopLevelSpecifiers ( ) .( PointerType ) .getBaseType ( ) and
299
+ not result instanceof VoidType
300
+ }
325
301
326
- predicate requiresDealloc ( AllocationFunction f ) { f .requiresDealloc ( ) }
302
+ predicate requiresDeallocImpl ( ) { target .requiresDealloc ( ) }
327
303
}
304
+ }
328
305
306
+ private module CallAllocationExpr {
329
307
/**
330
308
* A class that provides the implementation of `AllocationExpr` for an allocation
331
309
* that calls an `AllocationFunction`.
332
310
*/
333
- private class Base =
334
- CallAllocationExprBase< AllocationFunction > :: With< Param > :: CallAllocationExprImpl ;
311
+ private class Base = CallAllocationExprBase< AllocationFunction > :: CallAllocationExprImpl ;
335
312
336
313
class CallAllocationExpr extends AllocationExpr , Base {
337
314
override Expr getSizeExpr ( ) { result = super .getSizeExprImpl ( ) }
@@ -452,22 +429,11 @@ private module HeuristicAllocation {
452
429
override predicate requiresDealloc ( ) { none ( ) }
453
430
}
454
431
455
- private module Param implements CallAllocationExprBase< HeuristicAllocationFunction > :: Param {
456
- int getReallocPtrArg ( HeuristicAllocationFunction f ) { result = f .getReallocPtrArg ( ) }
457
-
458
- int getSizeArg ( HeuristicAllocationFunction f ) { result = f .getSizeArg ( ) }
459
-
460
- int getSizeMult ( HeuristicAllocationFunction f ) { result = f .getSizeMult ( ) }
461
-
462
- predicate requiresDealloc ( HeuristicAllocationFunction f ) { f .requiresDealloc ( ) }
463
- }
464
-
465
432
/**
466
433
* A class that provides the implementation of `AllocationExpr` for an allocation
467
434
* that calls an `HeuristicAllocationFunction`.
468
435
*/
469
- private class Base =
470
- CallAllocationExprBase< HeuristicAllocationFunction > :: With< Param > :: CallAllocationExprImpl ;
436
+ private class Base = CallAllocationExprBase< HeuristicAllocationFunction > :: CallAllocationExprImpl ;
471
437
472
438
private class CallAllocationExpr extends HeuristicAllocationExpr , Base {
473
439
override Expr getSizeExpr ( ) { result = super .getSizeExprImpl ( ) }
0 commit comments