1  /* { dg-do compile } */
       2  /* { dg-options "-fanalyzer" } */
       3  /* { dg-require-effective-target analyzer } */
       4  
       5  #include "gil.h"
       6  
       7  void test_1 (void)
       8  {
       9    Py_BEGIN_ALLOW_THREADS
      10    Py_END_ALLOW_THREADS
      11  }
      12  
      13  void test_2 (PyObject *obj)
      14  {
      15    Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
      16  
      17    Py_INCREF (obj); /* { dg-warning "use of PyObject '\\*obj' without the GIL" } */
      18    Py_DECREF (obj);
      19  
      20    Py_END_ALLOW_THREADS
      21  }
      22  
      23  void test_3 (PyObject *obj)
      24  {
      25    Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
      26  
      27    Py_BEGIN_ALLOW_THREADS /* { dg-warning "nested usage of 'Py_BEGIN_ALLOW_THREADS'" } */
      28    Py_END_ALLOW_THREADS
      29  
      30    Py_END_ALLOW_THREADS
      31  }
      32  
      33  void test_4 (PyObject *obj)
      34  {
      35    /* These aren't nested, so should be OK.  */
      36    Py_BEGIN_ALLOW_THREADS
      37    Py_END_ALLOW_THREADS
      38  
      39    Py_BEGIN_ALLOW_THREADS
      40    Py_END_ALLOW_THREADS
      41  }
      42  
      43  /* Interprocedural example of erroneously nested usage.  */
      44  
      45  static void  __attribute__((noinline))
      46  called_by_test_5 (void)
      47  {
      48    Py_BEGIN_ALLOW_THREADS /* { dg-warning "nested usage of 'Py_BEGIN_ALLOW_THREADS'" } */
      49    Py_END_ALLOW_THREADS
      50  }
      51  
      52  void test_5 (PyObject *obj)
      53  {
      54    Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
      55    called_by_test_5 ();
      56    Py_END_ALLOW_THREADS
      57  }
      58  
      59  /* Interprocedural example of bogusly using a PyObject outside of GIL.  */
      60  
      61  static void  __attribute__((noinline))
      62  called_by_test_6 (PyObject *obj)
      63  {
      64    Py_INCREF (obj); /* { dg-warning "use of PyObject '\\*obj' without the GIL" } */
      65    Py_DECREF (obj);
      66  }
      67  
      68  void test_6 (PyObject *obj)
      69  {
      70    Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
      71    called_by_test_6 (obj);
      72    Py_END_ALLOW_THREADS
      73  }
      74  
      75  extern void called_by_test_7 (PyObject *obj);
      76  
      77  void test_7 (PyObject *obj)
      78  {
      79    Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
      80    called_by_test_7 (obj); /* { dg-warning "use of PyObject as argument 1 of 'called_by_test_7' without the GIL" } */
      81    Py_END_ALLOW_THREADS
      82  }
      83  
      84  typedef void (*callback_t) (PyObject *);
      85  
      86  void test_8 (PyObject *obj, callback_t cb)
      87  {
      88    Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
      89    cb (obj); /* { dg-warning "use of PyObject as argument 1 of call without the GIL" } */
      90    Py_END_ALLOW_THREADS
      91  }