1  /* { dg-do run } */
       2  /* { dg-set-target-env-var ASAN_OPTIONS "detect_stack_use_after_return=1" } */
       3  /* { dg-shouldfail "asan" } */
       4  
       5  #include <stdio.h>
       6  #include <pthread.h>
       7  
       8  #ifndef kSize
       9  # define kSize 1
      10  #endif
      11  
      12  #ifndef UseThread
      13  # define UseThread 0
      14  #endif
      15  
      16  __attribute__((noinline))
      17  char *Ident(char *x) {
      18    fprintf(stderr, "1: %p\n", x);
      19    return x;
      20  }
      21  
      22  __attribute__((noinline))
      23  char *Func1() {
      24    char local[kSize];
      25    return Ident(local);
      26  }
      27  
      28  __attribute__((noinline))
      29  void Func2(char *x) {
      30    fprintf(stderr, "2: %p\n", x);
      31    *x = 1;
      32  }
      33  
      34  void *Thread(void *unused)  {
      35    Func2(Func1());
      36    return NULL;
      37  }
      38  
      39  int main(int argc, char **argv) {
      40  #if UseThread
      41    pthread_t t;
      42    pthread_create(&t, 0, Thread, 0);
      43    pthread_join(t, 0);
      44  #else
      45    Func2(Func1());
      46  #endif
      47    return 0;
      48  }
      49  
      50  /* { dg-output "WRITE of size 1 at .* thread T0.*" } */
      51  /* { dg-output "    #0.*(Func2)?.*use-after-return-1.(c:31)?.*" } */
      52  /* { dg-output "is located in stack of thread T0 at offset.*" } */
      53  /* { dg-output "\'local\' \\(line 24\\) <== Memory access at offset 32 is inside this variable" } */