@@ -206,7 +206,34 @@ private predicate deconstructSizeExpr(Expr sizeExpr, Expr lengthExpr, int sizeof
206206}
207207
208208/** 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+ }
210237
211238/**
212239 * This module abstracts over the type of allocation call-targets and provides a
@@ -220,118 +247,68 @@ private signature class CallAllocationExprTarget extends Function;
220247 * function using various heuristics.
221248 */
222249private 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-
253250 /**
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`.
257252 */
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 )
314265 }
315- }
316- }
317266
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+ }
321293
322- int getSizeArg ( AllocationFunction f ) { result = f . getSizeArg ( ) }
294+ Expr getReallocPtrImpl ( ) { result = super . getArgument ( target . getReallocPtrArg ( ) ) }
323295
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+ }
325301
326- predicate requiresDealloc ( AllocationFunction f ) { f .requiresDealloc ( ) }
302+ predicate requiresDeallocImpl ( ) { target .requiresDealloc ( ) }
327303 }
304+ }
328305
306+ private module CallAllocationExpr {
329307 /**
330308 * A class that provides the implementation of `AllocationExpr` for an allocation
331309 * that calls an `AllocationFunction`.
332310 */
333- private class Base =
334- CallAllocationExprBase< AllocationFunction > :: With< Param > :: CallAllocationExprImpl ;
311+ private class Base = CallAllocationExprBase< AllocationFunction > :: CallAllocationExprImpl ;
335312
336313 class CallAllocationExpr extends AllocationExpr , Base {
337314 override Expr getSizeExpr ( ) { result = super .getSizeExprImpl ( ) }
@@ -452,22 +429,11 @@ private module HeuristicAllocation {
452429 override predicate requiresDealloc ( ) { none ( ) }
453430 }
454431
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-
465432 /**
466433 * A class that provides the implementation of `AllocationExpr` for an allocation
467434 * that calls an `HeuristicAllocationFunction`.
468435 */
469- private class Base =
470- CallAllocationExprBase< HeuristicAllocationFunction > :: With< Param > :: CallAllocationExprImpl ;
436+ private class Base = CallAllocationExprBase< HeuristicAllocationFunction > :: CallAllocationExprImpl ;
471437
472438 private class CallAllocationExpr extends HeuristicAllocationExpr , Base {
473439 override Expr getSizeExpr ( ) { result = super .getSizeExprImpl ( ) }
0 commit comments