1 /* { dg-do run } */
2 /* { dg-require-effective-target hwaddress_exec } */
3 /* { dg-additional-options "--param hwasan-random-frame-tag=1" } */
4 /* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
5 #include <alloca.h>
6 
7 /* This testcase checks that `alloca` calls ensure the `__hwasan_generate_tag`
8    function is called to initialize the base tag.  `alloca` calls are treated
9    differently to standard variables.  The prologue/epilogue sequence is
10    generated mainly based on normal stack-allocated objects.
11 
12    We want to ensure that though the `alloca` call is not poisoned/unpoisoned
13    by the prologue and epilogue, the use of them in a given function still
14    triggers the prologue sequence to emit a call to __hwasan_generate_tag (and
15    hence that any call to __hwasan_generate_tag is emitted in the unconditional
16    part of the function code).  */
17 
18 int choice = 0;
19 int record = 1;
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 __attribute__ ((noinline))
25 unsigned char
__hwasan_generate_tag()26 __hwasan_generate_tag ()
27 {
28   record = 0;
29   return 3;
30 }
31 #ifdef __cplusplus
32 }
33 #endif
34 
35 __attribute__ ((noinline))
36 int
generate_tag_was_missed(void)37 generate_tag_was_missed (void)
38 {
39   return record;
40 }
41 
42 __attribute__((noinline, noclone)) int
foo(char * a)43 foo (char *a)
44 {
45   int i, j = 0;
46   asm volatile ("" : "+r" (a) : : "memory");
47   for (i = 0; i < 12; i++)
48     j += a[i];
49   return j;
50 }
51 
52 int
main()53 main ()
54 {
55   if (choice)
56   {
57         char *x = (char *)alloca(100);
58         foo(x);
59   }
60   else
61   {
62         char *y = (char *)alloca(20);
63         foo(y);
64   }
65   return generate_tag_was_missed ();
66 }
67