Bug Summary

File:home/bhubbard/working/src/ceph/build/boost/src/Boost/libs/python/src/converter/registry.cpp
Warning:line 91, column 11
Called function pointer is null (null dereference)

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1// Copyright David Abrahams 2001.
2// Distributed under the Boost Software License, Version 1.0. (See
3// accompanying file LICENSE_1_0.txt or copy at
4// http://www.boost.org/LICENSE_1_0.txt)
5#include <boost/python/converter/registry.hpp>
6#include <boost/python/converter/registrations.hpp>
7#include <boost/python/converter/builtin_converters.hpp>
8
9#include <set>
10#include <stdexcept>
11
12#if defined(__APPLE__) && defined(__MACH__) && defined(__GNUC__4) \
13 && __GNUC__4 == 3 && __GNUC_MINOR__2 <= 4 && !defined(__APPLE_CC__)
14# define BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND
15#endif
16
17#if defined(BOOST_PYTHON_TRACE_REGISTRY) \
18 || defined(BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND)
19# include <iostream>
20#endif
21
22namespace boost { namespace python { namespace converter {
23BOOST_PYTHON_DECL PyTypeObject const* registration::expected_from_python_type() const
24{
25 if (this->m_class_object != 0)
26 return this->m_class_object;
27
28 std::set<PyTypeObject const*> pool;
29
30 for(rvalue_from_python_chain* r = rvalue_chain; r ; r=r->next)
31 if(r->expected_pytype)
32 pool.insert(r->expected_pytype());
33
34 //for now I skip the search for common base
35 if (pool.size()==1)
36 return *pool.begin();
37
38 return 0;
39
40}
41
42BOOST_PYTHON_DECL PyTypeObject const* registration::to_python_target_type() const
43{
44 if (this->m_class_object != 0)
45 return this->m_class_object;
46
47 if (this->m_to_python_target_type != 0)
48 return this->m_to_python_target_type();
49
50 return 0;
51}
52
53BOOST_PYTHON_DECL PyTypeObject* registration::get_class_object() const
54{
55 if (this->m_class_object == 0)
56 {
57 ::PyErr_Format(
58 PyExc_TypeError
59 , const_cast<char*>("No Python class registered for C++ class %s")
60 , this->target_type.name());
61
62 throw_error_already_set();
63 }
64
65 return this->m_class_object;
66}
67
68BOOST_PYTHON_DECL PyObject* registration::to_python(void const volatile* source) const
69{
70 if (this->m_to_python == 0)
1
Assuming pointer value is null
2
Taking true branch
71 {
72 handle<> msg(
73#if PY_VERSION_HEX((2 << 24) | (7 << 16) | (12 << 8) | (0xF <<
4) | (0 << 0))
>= 0x3000000
74 ::PyUnicode_FromFormatPyUnicodeUCS4_FromFormat
75#else
76 ::PyString_FromFormat
77#endif
78 (
79 "No to_python (by-value) converter found for C++ type: %s"
80 , this->target_type.name()
81 )
82 );
83
84 PyErr_SetObject(PyExc_TypeError, msg.get());
85
86 throw_error_already_set();
87 }
88
89 return source == 0
3
Assuming 'source' is not equal to null
4
'?' condition is false
90 ? incref(Py_None(&_Py_NoneStruct))
91 : this->m_to_python(const_cast<void*>(source));
5
Called function pointer is null (null dereference)
92}
93
94namespace
95{
96 template< typename T >
97 void delete_node( T* node )
98 {
99 if( !!node && !!node->next )
100 delete_node( node->next );
101 delete node;
102 }
103}
104
105registration::~registration()
106{
107 delete_node(lvalue_chain);
108 delete_node(rvalue_chain);
109}
110
111
112namespace // <unnamed>
113{
114 typedef registration entry;
115
116 typedef std::set<entry> registry_t;
117
118#ifndef BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND
119 registry_t& entries()
120 {
121 static registry_t registry;
122
123# ifndef BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
124 static bool builtin_converters_initialized = false;
125 if (!builtin_converters_initialized)
126 {
127 // Make this true early because registering the builtin
128 // converters will cause recursion.
129 builtin_converters_initialized = true;
130
131 initialize_builtin_converters();
132 }
133# ifdef BOOST_PYTHON_TRACE_REGISTRY
134 std::cout << "registry: ";
135 for (registry_t::iterator p = registry.begin(); p != registry.end(); ++p)
136 {
137 std::cout << p->target_type << "; ";
138 }
139 std::cout << '\n';
140# endif
141# endif
142 return registry;
143 }
144#else
145 registry_t& static_registry()
146 {
147 static registry_t result;
148 return result;
149 }
150
151 bool static_builtin_converters_initialized()
152 {
153 static bool result = false;
154 if (result == false) {
155 result = true;
156 std::cout << std::flush;
157 return false;
158 }
159 return true;
160 }
161
162 registry_t& entries()
163 {
164# ifndef BOOST_PYTHON_SUPPRESS_REGISTRY_INITIALIZATION
165 if (!static_builtin_converters_initialized())
166 {
167 initialize_builtin_converters();
168 }
169# ifdef BOOST_PYTHON_TRACE_REGISTRY
170 std::cout << "registry: ";
171 for (registry_t::iterator p = static_registry().begin(); p != static_registry().end(); ++p)
172 {
173 std::cout << p->target_type << "; ";
174 }
175 std::cout << '\n';
176# endif
177# endif
178 return static_registry();
179 }
180#endif // BOOST_PYTHON_CONVERTER_REGISTRY_APPLE_MACH_WORKAROUND
181
182 entry* get(type_info type, bool is_shared_ptr = false)
183 {
184# ifdef BOOST_PYTHON_TRACE_REGISTRY
185 registry_t::iterator p = entries().find(entry(type));
186
187 std::cout << "looking up " << type << ": "
188 << (p == entries().end() || p->target_type != type
189 ? "...NOT found\n" : "...found\n");
190# endif
191 std::pair<registry_t::const_iterator,bool> pos_ins
192 = entries().insert(entry(type,is_shared_ptr));
193
194# if __MWERKS__ >= 0x3000
195 // do a little invariant checking if a change was made
196 if ( pos_ins.second )
197 assert(entries().invariants())(static_cast<void> (0));
198# endif
199 return const_cast<entry*>(&*pos_ins.first);
200 }
201} // namespace <unnamed>
202
203namespace registry
204{
205 void insert(to_python_function_t f, type_info source_t, PyTypeObject const* (*to_python_target_type)())
206 {
207# ifdef BOOST_PYTHON_TRACE_REGISTRY
208 std::cout << "inserting to_python " << source_t << "\n";
209# endif
210 entry* slot = get(source_t);
211
212 assert(slot->m_to_python == 0)(static_cast<void> (0)); // we have a problem otherwise
213 if (slot->m_to_python != 0)
214 {
215 std::string msg = (
216 std::string("to-Python converter for ")
217 + source_t.name()
218 + " already registered; second conversion method ignored."
219 );
220
221 if ( ::PyErr_Warn( NULL, const_cast<char*>(msg.c_str()) )PyErr_WarnEx(__null, const_cast<char*>(msg.c_str()), 1) )
222 {
223 throw_error_already_set();
224 }
225 }
226 slot->m_to_python = f;
227 slot->m_to_python_target_type = to_python_target_type;
228 }
229
230 // Insert an lvalue from_python converter
231 void insert(convertible_function convert, type_info key, PyTypeObject const* (*exp_pytype)())
232 {
233# ifdef BOOST_PYTHON_TRACE_REGISTRY
234 std::cout << "inserting lvalue from_python " << key << "\n";
235# endif
236 entry* found = get(key);
237 lvalue_from_python_chain *registration = new lvalue_from_python_chain;
238 registration->convert = convert;
239 registration->next = found->lvalue_chain;
240 found->lvalue_chain = registration;
241
242 insert(convert, 0, key,exp_pytype);
243 }
244
245 // Insert an rvalue from_python converter
246 void insert(convertible_function convertible
247 , constructor_function construct
248 , type_info key
249 , PyTypeObject const* (*exp_pytype)())
250 {
251# ifdef BOOST_PYTHON_TRACE_REGISTRY
252 std::cout << "inserting rvalue from_python " << key << "\n";
253# endif
254 entry* found = get(key);
255 rvalue_from_python_chain *registration = new rvalue_from_python_chain;
256 registration->convertible = convertible;
257 registration->construct = construct;
258 registration->expected_pytype = exp_pytype;
259 registration->next = found->rvalue_chain;
260 found->rvalue_chain = registration;
261 }
262
263 // Insert an rvalue from_python converter
264 void push_back(convertible_function convertible
265 , constructor_function construct
266 , type_info key
267 , PyTypeObject const* (*exp_pytype)())
268 {
269# ifdef BOOST_PYTHON_TRACE_REGISTRY
270 std::cout << "push_back rvalue from_python " << key << "\n";
271# endif
272 rvalue_from_python_chain** found = &get(key)->rvalue_chain;
273 while (*found != 0)
274 found = &(*found)->next;
275
276 rvalue_from_python_chain *registration = new rvalue_from_python_chain;
277 registration->convertible = convertible;
278 registration->construct = construct;
279 registration->expected_pytype = exp_pytype;
280 registration->next = 0;
281 *found = registration;
282 }
283
284 registration const& lookup(type_info key)
285 {
286 return *get(key);
287 }
288
289 registration const& lookup_shared_ptr(type_info key)
290 {
291 return *get(key, true);
292 }
293
294 registration const* query(type_info type)
295 {
296 registry_t::iterator p = entries().find(entry(type));
297# ifdef BOOST_PYTHON_TRACE_REGISTRY
298 std::cout << "querying " << type
299 << (p == entries().end() || p->target_type != type
300 ? "...NOT found\n" : "...found\n");
301# endif
302 return (p == entries().end() || p->target_type != type) ? 0 : &*p;
303 }
304} // namespace registry
305
306}}} // namespace boost::python::converter