@@ -205,57 +205,104 @@ private predicate deconstructSizeExpr(Expr sizeExpr, Expr lengthExpr, int sizeof
205
205
sizeof = 1
206
206
}
207
207
208
- /**
209
- * An allocation expression that is a function call, such as call to `malloc`.
210
- */
211
- private class CallAllocationExpr extends AllocationExpr , FunctionCall {
212
- AllocationFunction target ;
213
-
214
- CallAllocationExpr ( ) {
215
- target = this .getTarget ( ) and
216
- // realloc(ptr, 0) only frees the pointer
217
- not (
218
- exists ( target .getReallocPtrArg ( ) ) and
219
- this .getArgument ( target .getSizeArg ( ) ) .getValue ( ) .toInt ( ) = 0
220
- ) and
221
- // these are modeled directly (and more accurately), avoid duplication
222
- not exists ( NewOrNewArrayExpr new | new .getAllocatorCall ( ) = this )
223
- }
224
-
225
- override Expr getSizeExpr ( ) {
226
- exists ( Expr sizeExpr | sizeExpr = this .getArgument ( target .getSizeArg ( ) ) |
227
- if exists ( target .getSizeMult ( ) )
228
- then result = sizeExpr
229
- else
230
- exists ( Expr lengthExpr |
231
- deconstructSizeExpr ( sizeExpr , lengthExpr , _) and
232
- result = lengthExpr
208
+ private signature class CallAllocationExprTarget extends Function ;
209
+
210
+ private module CallAllocationExprBase< CallAllocationExprTarget Target> {
211
+ signature int getReallocPtrArgSig ( Target target ) ;
212
+
213
+ signature int getSizeArgSig ( Target target ) ;
214
+
215
+ signature int getSizeMultSig ( Target target ) ;
216
+
217
+ signature predicate requiresDeallocSig ( Target target ) ;
218
+
219
+ module With<
220
+ getReallocPtrArgSig / 1 getReallocPtrArg, getSizeArgSig / 1 getSizeArg, getSizeMultSig / 1 getSizeMult,
221
+ requiresDeallocSig / 1 requiresDealloc> {
222
+ /**
223
+ * An allocation expression that is a function call, such as call to `malloc`.
224
+ */
225
+ class CallAllocationExprImpl instanceof FunctionCall {
226
+ Target target ;
227
+
228
+ CallAllocationExprImpl ( ) {
229
+ target = this .getTarget ( ) and
230
+ // realloc(ptr, 0) only frees the pointer
231
+ not (
232
+ exists ( getReallocPtrArg ( target ) ) and
233
+ this .getArgument ( getSizeArg ( target ) ) .getValue ( ) .toInt ( ) = 0
234
+ ) and
235
+ // these are modeled directly (and more accurately), avoid duplication
236
+ not exists ( NewOrNewArrayExpr new | new .getAllocatorCall ( ) = this )
237
+ }
238
+
239
+ string toString ( ) { result = super .toString ( ) }
240
+
241
+ Expr getSizeExprImpl ( ) {
242
+ exists ( Expr sizeExpr | sizeExpr = super .getArgument ( getSizeArg ( target ) ) |
243
+ if exists ( getSizeMult ( target ) )
244
+ then result = sizeExpr
245
+ else
246
+ exists ( Expr lengthExpr |
247
+ deconstructSizeExpr ( sizeExpr , lengthExpr , _) and
248
+ result = lengthExpr
249
+ )
233
250
)
234
- )
251
+ }
252
+
253
+ int getSizeMultImpl ( ) {
254
+ // malloc with multiplier argument that is a constant
255
+ result = super .getArgument ( getSizeMult ( target ) ) .getValue ( ) .toInt ( )
256
+ or
257
+ // malloc with no multiplier argument
258
+ not exists ( getSizeMult ( target ) ) and
259
+ deconstructSizeExpr ( super .getArgument ( getSizeArg ( target ) ) , _, result )
260
+ }
261
+
262
+ int getSizeBytesImpl ( ) {
263
+ result = this .getSizeExprImpl ( ) .getValue ( ) .toInt ( ) * this .getSizeMultImpl ( )
264
+ }
265
+
266
+ Expr getReallocPtrImpl ( ) { result = super .getArgument ( getReallocPtrArg ( target ) ) }
267
+
268
+ Type getAllocatedElementTypeImpl ( ) {
269
+ result =
270
+ super .getFullyConverted ( ) .getType ( ) .stripTopLevelSpecifiers ( ) .( PointerType ) .getBaseType ( ) and
271
+ not result instanceof VoidType
272
+ }
273
+
274
+ predicate requiresDeallocImpl ( ) { requiresDealloc ( target ) }
275
+ }
235
276
}
277
+ }
236
278
237
- override int getSizeMult ( ) {
238
- // malloc with multiplier argument that is a constant
239
- result = this .getArgument ( target .getSizeMult ( ) ) .getValue ( ) .toInt ( )
240
- or
241
- // malloc with no multiplier argument
242
- not exists ( target .getSizeMult ( ) ) and
243
- deconstructSizeExpr ( this .getArgument ( target .getSizeArg ( ) ) , _, result )
244
- }
279
+ private module CallAllocationExpr {
280
+ private int getReallocPtrArg ( AllocationFunction f ) { result = f .getReallocPtrArg ( ) }
245
281
246
- override int getSizeBytes ( ) {
247
- result = this .getSizeExpr ( ) .getValue ( ) .toInt ( ) * this .getSizeMult ( )
248
- }
282
+ private int getSizeArg ( AllocationFunction f ) { result = f .getSizeArg ( ) }
249
283
250
- override Expr getReallocPtr ( ) { result = this . getArgument ( target . getReallocPtrArg ( ) ) }
284
+ private int getSizeMult ( AllocationFunction f ) { result = f . getSizeMult ( ) }
251
285
252
- override Type getAllocatedElementType ( ) {
253
- result =
254
- this .getFullyConverted ( ) .getType ( ) .stripTopLevelSpecifiers ( ) .( PointerType ) .getBaseType ( ) and
255
- not result instanceof VoidType
256
- }
286
+ private predicate requiresDealloc ( AllocationFunction f ) { f .requiresDealloc ( ) }
287
+
288
+ private class Base =
289
+ CallAllocationExprBase< AllocationFunction > :: With< getReallocPtrArg / 1 , getSizeArg / 1 , getSizeMult / 1 , requiresDealloc / 1 > :: CallAllocationExprImpl ;
290
+
291
+ class CallAllocationExpr extends AllocationExpr , Base {
292
+ override Expr getSizeExpr ( ) { result = super .getSizeExprImpl ( ) }
293
+
294
+ override int getSizeMult ( ) { result = super .getSizeMultImpl ( ) }
257
295
258
- override predicate requiresDealloc ( ) { target .requiresDealloc ( ) }
296
+ override Type getAllocatedElementType ( ) { result = super .getAllocatedElementTypeImpl ( ) }
297
+
298
+ override predicate requiresDealloc ( ) { super .requiresDeallocImpl ( ) }
299
+
300
+ override int getSizeBytes ( ) { result = super .getSizeBytesImpl ( ) }
301
+
302
+ override Expr getReallocPtr ( ) { result = super .getReallocPtrImpl ( ) }
303
+
304
+ override string toString ( ) { result = AllocationExpr .super .toString ( ) }
305
+ }
259
306
}
260
307
261
308
/**
@@ -294,3 +341,85 @@ private class NewArrayAllocationExpr extends AllocationExpr, NewArrayExpr {
294
341
295
342
override predicate requiresDealloc ( ) { not exists ( this .getPlacementPointer ( ) ) }
296
343
}
344
+
345
+ private module HeuristicAllocation {
346
+ private class HeuristicAllocationModeled extends HeuristicAllocationExpr instanceof AllocationExpr {
347
+ override Expr getSizeExpr ( ) { result = AllocationExpr .super .getSizeExpr ( ) }
348
+
349
+ override int getSizeMult ( ) { result = AllocationExpr .super .getSizeMult ( ) }
350
+
351
+ override int getSizeBytes ( ) { result = AllocationExpr .super .getSizeBytes ( ) }
352
+
353
+ override Expr getReallocPtr ( ) { result = AllocationExpr .super .getReallocPtr ( ) }
354
+
355
+ override Type getAllocatedElementType ( ) {
356
+ result = AllocationExpr .super .getAllocatedElementType ( )
357
+ }
358
+
359
+ override predicate requiresDealloc ( ) { AllocationExpr .super .requiresDealloc ( ) }
360
+ }
361
+
362
+ private class HeuristicAllocationFunctionModeled extends HeuristicAllocationFunction instanceof AllocationFunction {
363
+ override int getSizeArg ( ) { result = AllocationFunction .super .getSizeArg ( ) }
364
+
365
+ override int getSizeMult ( ) { result = AllocationFunction .super .getSizeMult ( ) }
366
+
367
+ override int getReallocPtrArg ( ) { result = AllocationFunction .super .getReallocPtrArg ( ) }
368
+
369
+ override predicate requiresDealloc ( ) { AllocationFunction .super .requiresDealloc ( ) }
370
+ }
371
+
372
+ private int getAnUnsignedParameter ( Function f ) {
373
+ f .getParameter ( result ) .getUnspecifiedType ( ) .( IntegralType ) .isUnsigned ( )
374
+ }
375
+
376
+ private int getAPointerParameter ( Function f ) {
377
+ f .getParameter ( result ) .getUnspecifiedType ( ) instanceof PointerType
378
+ }
379
+
380
+ private class HeuristicAllocationFunctionByName extends HeuristicAllocationFunction instanceof Function {
381
+ int sizeArg ;
382
+
383
+ HeuristicAllocationFunctionByName ( ) {
384
+ Function .super .getName ( ) .matches ( "%alloc%" ) and
385
+ Function .super .getUnspecifiedType ( ) instanceof PointerType and
386
+ sizeArg = unique( | | getAnUnsignedParameter ( this ) )
387
+ }
388
+
389
+ override int getSizeArg ( ) { result = sizeArg }
390
+
391
+ override int getReallocPtrArg ( ) {
392
+ Function .super .getName ( ) .matches ( "%realloc%" ) and
393
+ result = unique( | | getAPointerParameter ( this ) )
394
+ }
395
+
396
+ override predicate requiresDealloc ( ) { none ( ) }
397
+ }
398
+
399
+ private int getReallocPtrArg ( HeuristicAllocationFunction f ) { result = f .getReallocPtrArg ( ) }
400
+
401
+ private int getSizeArg ( HeuristicAllocationFunction f ) { result = f .getSizeArg ( ) }
402
+
403
+ private int getSizeMult ( HeuristicAllocationFunction f ) { result = f .getSizeMult ( ) }
404
+
405
+ private predicate requiresDealloc ( HeuristicAllocationFunction f ) { f .requiresDealloc ( ) }
406
+
407
+ private class Base =
408
+ CallAllocationExprBase< HeuristicAllocationFunction > :: With< getReallocPtrArg / 1 , getSizeArg / 1 , getSizeMult / 1 , requiresDealloc / 1 > :: CallAllocationExprImpl ;
409
+
410
+ private class CallAllocationExpr extends HeuristicAllocationExpr , Base {
411
+ override Expr getSizeExpr ( ) { result = super .getSizeExprImpl ( ) }
412
+
413
+ override int getSizeMult ( ) { result = super .getSizeMultImpl ( ) }
414
+
415
+ override Type getAllocatedElementType ( ) { result = super .getAllocatedElementTypeImpl ( ) }
416
+
417
+ override predicate requiresDealloc ( ) { super .requiresDeallocImpl ( ) }
418
+
419
+ override int getSizeBytes ( ) { result = super .getSizeBytesImpl ( ) }
420
+
421
+ override Expr getReallocPtr ( ) { result = super .getReallocPtrImpl ( ) }
422
+
423
+ override string toString ( ) { result = HeuristicAllocationExpr .super .toString ( ) }
424
+ }
425
+ }
0 commit comments