1 /* { dg-additional-options "-fanalyzer-transitivity" } */ 2 3 #include <stddef.h> 4 #include <alloca.h> 5 #include <stdlib.h> 6 7 extern void do_stuff (const void *); 8 9 #define LIMIT 1024 10 test_1(size_t sz)11void test_1 (size_t sz) 12 { 13 void *ptr; 14 if (sz >= LIMIT) 15 ptr = malloc (sz); 16 else 17 ptr = alloca (sz); 18 19 do_stuff (ptr); 20 21 if (sz >= LIMIT) 22 free (ptr); 23 } 24 test_2(size_t sz)25void test_2 (size_t sz) 26 { 27 void *ptr; 28 if (sz < LIMIT) 29 ptr = alloca (sz); 30 else 31 ptr = malloc (sz); 32 33 do_stuff (ptr); 34 35 if (sz >= LIMIT) 36 free (ptr); 37 } 38 test_3(size_t sz)39void test_3 (size_t sz) 40 { 41 void *ptr; 42 if (sz <= LIMIT) 43 ptr = alloca (sz); /* { dg-message "memory is allocated on the stack here" } */ 44 else 45 ptr = malloc (sz); 46 47 do_stuff (ptr); 48 49 /* Bug: the "sz <= LIMIT" above should have been "sz < LIMIT", 50 so there's a free-of-alloca when sz == LIMIT. */ 51 if (sz >= LIMIT) 52 free (ptr); /* { dg-warning "'free' of memory allocated on the stack by 'alloca'" } */ 53 } 54 /* { dg-bogus "leak of 'ptr'" } */ 55 /* This can't happen, as "sz > 1024" && "sz <= 1023" is impossible. */ 56