(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
putenv-1.c
       1  /* { dg-additional-options "-Wno-analyzer-null-argument" } */
       2  /* { dg-require-effective-target alloca } */
       3  
       4  #include <stdio.h>
       5  #include <stdlib.h>
       6  
       7  extern void populate (char *buf);
       8  
       9  void test_passthrough (char *s)
      10  {
      11    putenv (s);
      12  }
      13  
      14  void test_str_lit (void)
      15  {
      16    putenv ("NAME=value");
      17  }
      18  
      19  /* glibc allows strings without an equal sign.  */
      20  
      21  void test_no_eq (void)
      22  {
      23    putenv ("NAME");
      24  }
      25  
      26  void test_empty_string (void)
      27  {
      28    putenv ("");
      29  }
      30  
      31  void test_NULL (void)
      32  {
      33    putenv (NULL); /* possibly -Wanalyzer-null-argument */
      34  }
      35  
      36  void test_auto_buf_name_and_value (const char *name, const char *value)
      37  {
      38    char buf[100]; /* { dg-message "'buf' declared on stack here" } */
      39    snprintf (buf, sizeof (buf), "%s=%s", name, value);
      40    putenv (buf); /* { dg-warning "'putenv' on a pointer to automatic variable 'buf' \\\[POS34-C\\\]" "warning" } */
      41    /* { dg-message "perhaps use 'setenv' rather than 'putenv'" "setenv suggestion" { target *-*-* } .-1 } */
      42  }
      43  
      44  void test_auto_buf_value (const char *value)
      45  {
      46    char buf[100]; /* { dg-message "'buf' declared on stack here" } */
      47    snprintf (buf, sizeof (buf), "NAME=%s", value);
      48    putenv (buf); /* { dg-warning "'putenv' on a pointer to automatic variable 'buf' \\\[POS34-C\\\]" } */
      49  }
      50  
      51  void test_static_buf (const char *value)
      52  {
      53    static char buf[100];
      54    snprintf (buf, sizeof (buf), "NAME=%s", value);
      55    putenv (buf);
      56  }
      57  
      58  static char global_buf[1024];
      59  
      60  void test_global (const char *value)
      61  {
      62    snprintf (global_buf, sizeof (global_buf), "NAME=%s", value);
      63    putenv (global_buf);
      64  }
      65  
      66  void test_alloca (void)
      67  {
      68    char *buf = __builtin_alloca (256); /* { dg-message "region created on stack here" } */
      69    populate (buf);
      70    putenv (buf); /* { dg-warning "'putenv' on a pointer to an on-stack buffer \\\[POS34-C\\\]" } */
      71  }
      72  
      73  void test_malloc_1 (void)
      74  {
      75    char *buf = malloc (1024);
      76    if (!buf)
      77      return;
      78    populate (buf);
      79    putenv (buf);
      80  }
      81  
      82  void test_malloc_2 (void)
      83  {
      84    const char *kvstr = "NAME=value";
      85    size_t len = __builtin_strlen (kvstr);
      86    char *buf = __builtin_malloc (len + 1);
      87    if (!buf)
      88      return;
      89    __builtin_memcpy (buf, kvstr, len);
      90    buf[len] = '\0';
      91    putenv (buf); /* { dg-bogus "leak" } */
      92  }
      93  
      94  void test_arr (void)
      95  {
      96    char arr[] = "NAME=VALUE"; /* { dg-message "'arr' declared on stack here" } */
      97    putenv (arr); /* { dg-warning "'putenv' on a pointer to automatic variable 'arr' \\\[POS34-C\\\]" } */
      98  }
      99  
     100  static void __attribute__((noinline))
     101  __analyzer_test_inner (char *kvstr)
     102  {
     103    putenv (kvstr); /* { dg-warning "'putenv' on a pointer to automatic variable 'arr_outer' \\\[POS34-C\\\]" } */
     104  }
     105  
     106  void test_outer (void)
     107  {
     108    char arr_outer[] = "NAME=VALUE"; /* { dg-message "'arr_outer' declared on stack here" } */
     109    __analyzer_test_inner (arr_outer);
     110  }