select_types(PyUFuncObject *self, int *arg_types,
             PyUFuncGenericFunction *function, void **data,
             PyArray_SCALARKIND *scalars,
             PyObject *typetup)
{
    int i, j;
    char start_type;
    int userdef=-1;
    int userdef_ind=-1;

    if (self->userloops) {
        for(i=0; i<self->nin; i++) {
            if (PyTypeNum_ISUSERDEF(arg_types[i])) {
                userdef = arg_types[i];
        userdef_ind = i;
                break;
            }
        }
    }

    if (typetup != NULL)
        return extract_specified_loop(self, arg_types, function, data,
                                      typetup, userdef);

    if (userdef > 0) {
       ^^^^^^^^^^^^
        PyObject *key, *obj;
        int ret=-1;
        obj = NULL;
    /* Look through all the registered loops for all the user-defined
       types to find a match.
     */
    while (ret == -1) {
        if (userdef_ind >= self->nin) break;
        userdef = arg_types[userdef_ind++];
        if (!(PyTypeNum_ISUSERDEF(userdef))) continue;
        key = PyInt_FromLong((long) userdef);
        if (key == NULL) return -1;
        obj = PyDict_GetItem(self->userloops, key);
        Py_DECREF(key);
        if (obj == NULL) continue;
        /* extract the correct function
           data and argtypes for this user-defined type.
        */
        ret = _find_matching_userloop(obj, arg_types, scalars,
                      function, data, self->nargs,
                      self->nin);
    }
    if (ret == 0) return ret;
    PyErr_SetString(PyExc_TypeError, _types_msg);
    return ret;
    }
...

It looks like the test should be userdef >= 0.

Chuck