Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Intermediate bool value cast as PyObject * and DECREFed #5731

Closed
LinAGKar opened this issue Sep 28, 2023 · 2 comments · Fixed by #5735
Closed

[BUG] Intermediate bool value cast as PyObject * and DECREFed #5731

LinAGKar opened this issue Sep 28, 2023 · 2 comments · Fixed by #5735

Comments

@LinAGKar
Copy link

Describe the bug

In the result of the example code given below, I get:

  /* "test.pyx":10
 * 
 * def f2(x):
 * 	f1(False if x is None else x)             # <<<<<<<<<<<<<<
 * 
 * f2(None)
 */
  __pyx_t_2 = (__pyx_v_x == Py_None);
  if (__pyx_t_2) {
    __pyx_t_1 = ((PyObject *)0);
  } else {
    __pyx_t_3 = __Pyx_PyInt_As_bool(__pyx_v_x); if (unlikely((__pyx_t_3 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 10, __pyx_L1_error)
    __pyx_t_1 = ((PyObject *)__pyx_t_3);
  }
  __pyx_t_4 = __pyx_f_4test_f1(((bool)__pyx_t_1)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 10, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;

So it's taking the bool from the if expression (0 or __pyx_t_3, depending on the branch), and casting it to a PyObject * (__pyx_t_1). Then later it casts the pointer back into a bool to pass it to the function, which works, but afterwards it tries to call __Pyx_DECREF on it, causing a segfault.

Code to reproduce the behaviour:

# cython: language_level=3

cdef extern from "<stdbool.h>":
	ctypedef int bool

cdef f1(bool x):
	pass

def f2(x):
	f1(False if x is None else x)

f2(None)

Built with cython --embed

Expected behaviour

In the C code above, __pyx_t_1 should be a bool.

OS

Linux

Python version

3.9.18

Cython version

3.0.2

Additional context

No response

@da-woods
Copy link
Contributor

It's in 0.29.x too so doesn't appear to be a regression. The typedef also isn't relevant - just defining f1 as int works the same.

@da-woods
Copy link
Contributor

There's also two issues

    __pyx_t_1 = ((PyObject *)__pyx_t_3);

is also wrong

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants