Fix typecheck typemaps for non-pointers and NULL

The typecheck typemaps succeed for non pointers (SWIGTYPE, SWIGTYPE&,
SWIGTYPE&&) when the equivalent to C NULL is passed from the target
language. This commit implements a fix for Python to not accept a Python
None for non-pointer types.

Issue #1202
This commit is contained in:
William S Fulton 2018-12-29 11:45:46 +00:00
commit 3efea1f4ab
4 changed files with 11 additions and 18 deletions

View file

@ -13,15 +13,7 @@ check(1, A(1).get())
check(2, A(1.0).get()) check(2, A(1.0).get())
check(3, A(B()).get()) check(3, A(B()).get())
check(4, A("hello").get()) check(4, A("hello").get())
try: check(4, A(None).get())
check(3, A(None).get())
raise RuntimeError
except ValueError:
# ValueError: invalid null reference in method 'new_A', argument 1 of type 'B const &'
# Arguably A(char *) should be chosen, but there is a bug to do with None passed to methods overloaded by value,
# references and pointers to different types, where pointers ought to be
# given a slightly higher precedence.
pass
check(1, get(1)) check(1, get(1))
check(2, get(1.0)) check(2, get(1.0))

View file

@ -1018,7 +1018,7 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int
if (obj == Py_None && !implicit_conv) { if (obj == Py_None && !implicit_conv) {
if (ptr) if (ptr)
*ptr = 0; *ptr = 0;
return SWIG_OK; return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
} }
res = SWIG_ERROR; res = SWIG_ERROR;

View file

@ -43,6 +43,7 @@
/* Flags for pointer conversions */ /* Flags for pointer conversions */
#define SWIG_POINTER_DISOWN 0x1 #define SWIG_POINTER_DISOWN 0x1
#define SWIG_CAST_NEW_MEMORY 0x2 #define SWIG_CAST_NEW_MEMORY 0x2
#define SWIG_POINTER_NO_NULL 0x4
/* Flags for new pointer objects */ /* Flags for new pointer objects */
#define SWIG_POINTER_OWN 0x1 #define SWIG_POINTER_OWN 0x1

View file

@ -358,46 +358,46 @@
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE & { %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE & {
void *vptr = 0; void *vptr = 0;
int res = SWIG_ConvertPtr($input, &vptr, $descriptor, 0); int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
$1 = SWIG_CheckState(res); $1 = SWIG_CheckState(res);
} }
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE && { %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE && {
void *vptr = 0; void *vptr = 0;
int res = SWIG_ConvertPtr($input, &vptr, $descriptor, 0); int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
$1 = SWIG_CheckState(res); $1 = SWIG_CheckState(res);
} }
#if defined(__cplusplus) && defined(%implicitconv_flag) #if defined(__cplusplus) && defined(%implicitconv_flag)
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) const SWIGTYPE & { %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) const SWIGTYPE & {
int res = SWIG_ConvertPtr($input, 0, $descriptor, %implicitconv_flag); int res = SWIG_ConvertPtr($input, 0, $descriptor, SWIG_POINTER_NO_NULL | %implicitconv_flag);
$1 = SWIG_CheckState(res); $1 = SWIG_CheckState(res);
} }
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) const SWIGTYPE && { %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) const SWIGTYPE && {
int res = SWIG_ConvertPtr($input, 0, $descriptor, %implicitconv_flag); int res = SWIG_ConvertPtr($input, 0, $descriptor, SWIG_POINTER_NO_NULL | %implicitconv_flag);
$1 = SWIG_CheckState(res); $1 = SWIG_CheckState(res);
} }
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) SWIGTYPE { %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) SWIGTYPE {
int res = SWIG_ConvertPtr($input, 0, $&descriptor, %implicitconv_flag); int res = SWIG_ConvertPtr($input, 0, $&descriptor, SWIG_POINTER_NO_NULL | %implicitconv_flag);
$1 = SWIG_CheckState(res); $1 = SWIG_CheckState(res);
} }
#else #else
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) const SWIGTYPE & { %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) const SWIGTYPE & {
void *vptr = 0; void *vptr = 0;
int res = SWIG_ConvertPtr($input, &vptr, $descriptor, 0); int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
$1 = SWIG_CheckState(res); $1 = SWIG_CheckState(res);
} }
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) const SWIGTYPE && { %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) const SWIGTYPE && {
void *vptr = 0; void *vptr = 0;
int res = SWIG_ConvertPtr($input, &vptr, $descriptor, 0); int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
$1 = SWIG_CheckState(res); $1 = SWIG_CheckState(res);
} }
%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE { %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE {
void *vptr = 0; void *vptr = 0;
int res = SWIG_ConvertPtr($input, &vptr, $&descriptor, 0); int res = SWIG_ConvertPtr($input, &vptr, $&descriptor, SWIG_POINTER_NO_NULL);
$1 = SWIG_CheckState(res); $1 = SWIG_CheckState(res);
} }
#endif #endif