File tree Expand file tree Collapse file tree 5 files changed +84
-2
lines changed
test/query-tests/Critical/MemoryFreed Expand file tree Collapse file tree 5 files changed +84
-2
lines changed Original file line number Diff line number Diff line change @@ -39,7 +39,7 @@ predicate allocCallOrIndirect(Expr e) {
39
39
allocCallOrIndirect ( rtn .getExpr ( ) )
40
40
or
41
41
// return variable assigned with alloc
42
- exists ( Variable v |
42
+ exists ( StackVariable v |
43
43
v = rtn .getExpr ( ) .( VariableAccess ) .getTarget ( ) and
44
44
allocCallOrIndirect ( v .getAnAssignedValue ( ) ) and
45
45
not assignedToFieldOrGlobal ( v , _)
Original file line number Diff line number Diff line change
1
+ ---
2
+ category : minorAnalysis
3
+ ---
4
+ * Fixed false positives in the ` cpp/memory-may-not-be-freed ` ("Memory may not be freed") query involving class methods that returned an allocated field of that class being misidentified as allocators.
Original file line number Diff line number Diff line change 120
120
| test_free.cpp:346:26:346:28 | ptr |
121
121
| test_free.cpp:356:19:356:19 | a |
122
122
| test_free.cpp:357:19:357:19 | a |
123
+ | test_free.cpp:370:10:370:10 | a |
124
+ | test_free.cpp:373:10:373:10 | e |
125
+ | test_free.cpp:382:10:382:10 | i |
126
+ | test_free.cpp:383:10:383:10 | s |
127
+ | test_free.cpp:395:14:395:19 | buffer |
128
+ | test_free.cpp:424:10:424:16 | buffer2 |
123
129
| virtual.cpp:18:10:18:10 | a |
124
130
| virtual.cpp:19:10:19:10 | c |
125
131
| virtual.cpp:38:10:38:10 | b |
Original file line number Diff line number Diff line change 14
14
| test_free.cpp:167:15:167:21 | call to realloc | This memory is never freed. |
15
15
| test_free.cpp:253:14:253:19 | call to malloc | This memory is never freed. |
16
16
| test_free.cpp:261:6:261:12 | new | This memory is never freed. |
17
+ | test_free.cpp:365:21:365:26 | call to malloc | This memory is never freed. |
18
+ | test_free.cpp:368:31:368:36 | call to malloc | This memory is never freed. |
Original file line number Diff line number Diff line change @@ -355,4 +355,74 @@ struct E {
355
355
void test (E* e) {
356
356
free (e->ec [0 ].a );
357
357
free (e->ec [1 ].a ); // GOOD
358
- }
358
+ }
359
+
360
+ // ---
361
+
362
+ void test_return_by_parameter (int **out_i, MyStruct **out_ms) {
363
+ int *a = (int *)malloc (sizeof (int )); // GOOD (freed)
364
+ int *b = (int *)malloc (sizeof (int )); // GOOD (out parameter)
365
+ int *d = (int *)malloc (sizeof (int )); // BAD (not freed)
366
+ MyStruct *e = (MyStruct *)malloc (sizeof (MyStruct)); // GOOD (freed)
367
+ MyStruct *f = (MyStruct *)malloc (sizeof (MyStruct)); // GOOD (out parameter)
368
+ MyStruct *h = (MyStruct *)malloc (sizeof (MyStruct)); // BAD (not freed)
369
+
370
+ free (a);
371
+ *out_i = b;
372
+
373
+ free (e);
374
+ *out_ms = f;
375
+ }
376
+
377
+ void test_return_by_parameter_caller () {
378
+ int *i;
379
+ MyStruct *s;
380
+
381
+ test_return_by_parameter (&i, &s);
382
+ free (i);
383
+ free (s);
384
+ }
385
+
386
+ // ---
387
+
388
+ class HasGetterAndFree {
389
+ public:
390
+ HasGetterAndFree () {
391
+ buffer = malloc (1024 );
392
+ }
393
+
394
+ ~HasGetterAndFree () {
395
+ free (buffer);
396
+ }
397
+
398
+ void *getBuffer () {
399
+ return buffer;
400
+ }
401
+
402
+ void *buffer;
403
+ };
404
+
405
+ class HasGetterNoFree {
406
+ public:
407
+ HasGetterNoFree () {
408
+ buffer = malloc (1024 );
409
+ }
410
+
411
+ void *getBuffer () {
412
+ return buffer;
413
+ }
414
+
415
+ void *buffer;
416
+ };
417
+
418
+ void testHasGetter () {
419
+ HasGetterAndFree hg;
420
+ void *buffer = hg.getBuffer (); // GOOD (freed in destructor)
421
+
422
+ HasGetterNoFree hg2;
423
+ void *buffer2 = hg2.getBuffer (); // GOOD (freed below)
424
+ free (buffer2);
425
+
426
+ HasGetterNoFree hg3;
427
+ void *buffer3 = hg3.getBuffer (); // BAD (not freed) [NOT DETECTED]
428
+ }
You can’t perform that action at this time.
0 commit comments