1  /* Verify how paths are printed for signal-handler diagnostics.  */
       2  
       3  /* { dg-options "-fanalyzer -fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
       4  /* { dg-enable-nn-line-numbers "" } */
       5  /* { dg-require-effective-target signal } */
       6  
       7  #include <stdio.h>
       8  #include <signal.h>
       9  #include <stdlib.h>
      10  
      11  extern void body_of_program(void);
      12  
      13  void custom_logger(const char *msg)
      14  {
      15    fprintf(stderr, "LOG: %s", msg); /* { dg-warning "call to 'fprintf' from within signal handler" } */
      16  }
      17  
      18  static void int_handler(int signum)
      19  {
      20    custom_logger("got signal");
      21  }
      22  
      23  static void __analyzer_register_handler ()
      24  {
      25    signal(SIGINT, int_handler);
      26  }
      27  
      28  void test (void)
      29  {
      30    __analyzer_register_handler ();
      31    body_of_program();
      32  }
      33  
      34  /* "call to 'fprintf' from within signal handler [CWE-479]".  */
      35  /* { dg-begin-multiline-output "" }
      36     NN |   fprintf(stderr, "LOG: %s", msg);
      37        |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      38    'test': events 1-2
      39      |
      40      |   NN | void test (void)
      41      |      |      ^~~~
      42      |      |      |
      43      |      |      (1) entry to 'test'
      44      |   NN | {
      45      |   NN |   __analyzer_register_handler ();
      46      |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      47      |      |   |
      48      |      |   (2) calling '__analyzer_register_handler' from 'test'
      49      |
      50      +--> '__analyzer_register_handler': events 3-4
      51             |
      52             |   NN | static void __analyzer_register_handler ()
      53             |      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~
      54             |      |             |
      55             |      |             (3) entry to '__analyzer_register_handler'
      56             |   NN | {
      57             |   NN |   signal(SIGINT, int_handler);
      58             |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      59             |      |   |
      60             |      |   (4) registering 'int_handler' as signal handler
      61             |
      62    event 5
      63      |
      64      |cc1:
      65      | (5): later on, when the signal is delivered to the process
      66      |
      67      +--> 'int_handler': events 6-7
      68             |
      69             |   NN | static void int_handler(int signum)
      70             |      |             ^~~~~~~~~~~
      71             |      |             |
      72             |      |             (6) entry to 'int_handler'
      73             |   NN | {
      74             |   NN |   custom_logger("got signal");
      75             |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
      76             |      |   |
      77             |      |   (7) calling 'custom_logger' from 'int_handler'
      78             |
      79             +--> 'custom_logger': events 8-9
      80                    |
      81                    |   NN | void custom_logger(const char *msg)
      82                    |      |      ^~~~~~~~~~~~~
      83                    |      |      |
      84                    |      |      (8) entry to 'custom_logger'
      85                    |   NN | {
      86                    |   NN |   fprintf(stderr, "LOG: %s", msg);
      87                    |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      88                    |      |   |
      89                    |      |   (9) call to 'fprintf' from within signal handler
      90                    |
      91    { dg-end-multiline-output "" } */