[C++-sig] Segfault with keyword arguments and overloads.
Alex Leach
beamesleach at gmail.com
Thu Aug 8 11:28:24 CEST 2013
Hi Alex,
On Wed, 07 Aug 2013 18:06:24 +0100, Alex Mohr <amohr at pixar.com> wrote:
> Thanks for your response. I've responded to your comments in-line below.
>
> After further investigation, I believe this can be fixed by simply
> checking for None when we get 'kv' from f->m_arg_names while resolving
> keywords. If we encounter None, that means the overload doesn't accept
> a keyword argument in that position (so not enough positional args were
> passed), and we can reject the overload.
>
> If it works, I think that's a simple, targeted fix that isn't
> particularly risky. I'll try to work up a patch.
>
Sounds like you missed it, but I did add a fairly simple patch to my
previous email. I used your code as a test case and it worked fine; no seg
faults. I've copied it again below...
I don't have commit privileges to Boost Python, but I think from your
explanations, that this is a valid bug in BP. So it would probably be
worthwhile filing a bug report, at
http://www.boost.org/development/bugs.html
Unless someone with commit privileges wants to consider merging it? My
only thought on the patch regards return value optimisation. Would moving
the `PyObject *` declarations out of the loop impair the compiler's
ability to perform RVO?
Hope that helps anyway.
Kind regards,
Alex
--- ./boost_1_53_0/libs/python/src/object/function.cpp.orig 2013-08-07
11:02:28.569236835 +0100
+++ ./boost_1_53_0/libs/python/src/object/function.cpp 2013-08-07
11:56:10.926045853 +0100
@@ -177,16 +177,18 @@
// Grab remaining arguments by name from the
keyword dictionary
std::size_t n_actual_processed = n_unnamed_actual;
+ PyObject *kv, *k, *value;
for (std::size_t arg_pos = n_unnamed_actual;
arg_pos < max_arity ; ++arg_pos)
{
// Get the keyword[, value pair] corresponding
- PyObject* kv =
PyTuple_GET_ITEM(f->m_arg_names.ptr(), arg_pos);
+ kv = PyTuple_GET_ITEM(f->m_arg_names.ptr(),
arg_pos);
// If there were any keyword arguments,
// look up the one we need for this
// argument position
- PyObject* value = n_keyword_actual
- ? PyDict_GetItem(keywords,
PyTuple_GET_ITEM(kv, 0))
+ k = PyTuple_GET_ITEM(kv, 0);
+ value = (k != NULL && n_keyword_actual)
+ ? PyDict_GetItem(keywords, k)
: 0;
if (!value)
More information about the Cplusplus-sig
mailing list