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)11 void 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)25 void 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)39 void 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