(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
analyzer/
attr-tainted_args-1.c
       1  // TODO: remove need for this option
       2  /* { dg-additional-options "-fanalyzer-checker=taint" } */
       3  
       4  #include "analyzer-decls.h"
       5  
       6  struct arg_buf
       7  {
       8    int i;
       9    int j;
      10  };
      11  
      12  /* Example of marking a function as tainted.  */
      13  
      14  void __attribute__((tainted_args))
      15  test_1 (int i, void *p, char *q)
      16  {
      17    /* There should be a single enode,
      18       for the "tainted" entry to the function.  */
      19    __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
      20  
      21    __analyzer_dump_state ("taint", i); /* { dg-warning "state: 'tainted'" } */
      22    __analyzer_dump_state ("taint", p); /* { dg-warning "state: 'tainted'" } */
      23    __analyzer_dump_state ("taint", q); /* { dg-warning "state: 'tainted'" } */
      24    __analyzer_dump_state ("taint", *q); /* { dg-warning "state: 'tainted'" } */
      25  
      26    struct arg_buf *args = p;
      27    __analyzer_dump_state ("taint", args->i); /* { dg-warning "state: 'tainted'" } */
      28    __analyzer_dump_state ("taint", args->j); /* { dg-warning "state: 'tainted'" } */  
      29  }
      30  
      31  /* Example of marking a callback field as tainted.  */
      32  
      33  struct s2
      34  {
      35    void (*cb) (int, void *, char *)
      36      __attribute__((tainted_args));
      37  };
      38  
      39  /* Function not marked as tainted.  */
      40  
      41  void
      42  test_2a (int i, void *p, char *q)
      43  {
      44    /* There should be a single enode,
      45       for the normal entry to the function.  */
      46    __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
      47  
      48    __analyzer_dump_state ("taint", i); /* { dg-warning "state: 'start'" } */
      49    __analyzer_dump_state ("taint", p); /* { dg-warning "state: 'start'" } */
      50    __analyzer_dump_state ("taint", q); /* { dg-warning "state: 'start'" } */
      51  
      52    struct arg_buf *args = p;
      53    __analyzer_dump_state ("taint", args->i); /* { dg-warning "state: 'start'" } */
      54    __analyzer_dump_state ("taint", args->j); /* { dg-warning "state: 'start'" } */  
      55  }
      56  
      57  /* Function referenced via t2b.cb, marked as "tainted".  */
      58  
      59  void
      60  test_2b (int i, void *p, char *q)
      61  {
      62    /* There should be two enodes
      63       for the direct call, and the "tainted" entry to the function.  */
      64    __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
      65  }
      66  
      67  /* Callback used via t2c.cb, marked as "tainted".  */
      68  void
      69  __analyzer_test_2c (int i, void *p, char *q)
      70  {
      71    /* There should be a single enode,
      72       for the "tainted" entry to the function.  */
      73    __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
      74  
      75    __analyzer_dump_state ("taint", i); /* { dg-warning "state: 'tainted'" } */
      76    __analyzer_dump_state ("taint", p); /* { dg-warning "state: 'tainted'" } */
      77    __analyzer_dump_state ("taint", q); /* { dg-warning "state: 'tainted'" } */
      78  }
      79  
      80  struct s2 t2b =
      81  {
      82    .cb = test_2b
      83  };
      84  
      85  struct s2 t2c =
      86  {
      87    .cb = __analyzer_test_2c
      88  };