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
      26  __hwasan_generate_tag ()
      27  {
      28    record = 0;
      29    return 3;
      30  }
      31  #ifdef __cplusplus
      32  }
      33  #endif
      34  
      35  __attribute__ ((noinline))
      36  int
      37  generate_tag_was_missed (void)
      38  {
      39    return record;
      40  }
      41  
      42  __attribute__((noinline, noclone)) int
      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
      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  }