<p dir="auto">In <code class="notranslate">scipy/integrate/quadpack.h</code>, function <code class="notranslate">init_c_multivariate</code> stores a pointer to <code class="notranslate">n_args_ref</code> in the global variable <code class="notranslate">global_n_args</code>. Unfortunately <code class="notranslate">n_args_ref</code> is a local variable which very soon goes out of scope, so later dereferencing <code class="notranslate">global_n_args</code> produces a nonsensical value.</p>
<p dir="auto">This code looks wrong: <a href="https://github.com/scipy/scipy/blob/master/scipy/integrate/__quadpack.h#L128">https://github.com/scipy/scipy/blob/master/scipy/integrate/__quadpack.h#L128</a></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="  check = PyObject_GetAttrString(func, &quot;argtypes&quot;);
  if (!PyTuple_Check(check) || (PyTuple_GET_SIZE(check) != 1) || 
      (PyTuple_GET_ITEM(check, 0) != c_double)) {
    if ((PyTuple_GET_ITEM(check, 0) == c_int) &amp;&amp; (PyTuple_GET_ITEM(check, 1) == c_double)){   
      /*If first param is int and second is of double type, we have valid_multivariate */
       ...
       return Valid_Multivariate_Ctype;
    }
    else 
      goto fail;
  }"><pre class="notranslate"><code class="notranslate">  check = PyObject_GetAttrString(func, "argtypes");
  if (!PyTuple_Check(check) || (PyTuple_GET_SIZE(check) != 1) || 
      (PyTuple_GET_ITEM(check, 0) != c_double)) {
    if ((PyTuple_GET_ITEM(check, 0) == c_int) &amp;&amp; (PyTuple_GET_ITEM(check, 1) == c_double)){   
      /*If first param is int and second is of double type, we have valid_multivariate */
       ...
       return Valid_Multivariate_Ctype;
    }
    else 
      goto fail;
  }
</code></pre></div>
<p dir="auto">The argument checks are done wrong (PyTuple_GET_ITEM called even if PyTuple_Check fails, etc).</p>
<p dir="auto">Moreover, the actual argument type used later on is a pointer to a double, not double. The check should check that.</p>
<p dir="auto">The check at <a href="https://github.com/scipy/scipy/blob/master/scipy/integrate/__quadpack.h#L396">https://github.com/scipy/scipy/blob/master/scipy/integrate/__quadpack.h#L396</a> should check for equality, not inequality.</p>
<p dir="auto">This code stores a pointer to a local variable, which is invalid: <a href="https://github.com/scipy/scipy/blob/master/scipy/integrate/quadpack.h#L176">https://github.com/scipy/scipy/blob/master/scipy/integrate/quadpack.h#L176</a></p>
<p dir="auto">The code stores pointers of different types in <code class="notranslate">global_args</code> and <code class="notranslate">storage-&gt;args</code>, e.g. <a href="https://github.com/scipy/scipy/blob/master/scipy/integrate/quadpack.h#L170">https://github.com/scipy/scipy/blob/master/scipy/integrate/quadpack.h#L170</a>. These variables should be <code class="notranslate">void*</code>, not <code class="notranslate">PyObject*</code>.</p>
<p dir="auto">I didn't have time to look at the PR that added these at the time...</p>