[C++-sig] boost/python 1.33.1 breaks aliasing rules

Philipp Thomas pth at suse.de
Wed Dec 7 17:16:28 CET 2005


* Philipp Thomas (pth at suse.de) [20051207 14:27]:

> I'll do a patch that changes all affected places

And here is the patch I'm going to be using for SUSE Linux:

--- libs/python/src/dict.cpp
+++ libs/python/src/dict.cpp
@@ -28,9 +28,9 @@
 
 detail::new_reference dict_base::call(object const& arg_)
 {
+    union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyDict_Type };
     return (detail::new_reference)PyObject_CallFunction(
-        (PyObject*)&PyDict_Type, "(O)", 
-        arg_.ptr());
+        pun.pop, "(O)", arg_.ptr());
 }
 
 dict_base::dict_base()
--- libs/python/src/list.cpp
+++ libs/python/src/list.cpp
@@ -9,10 +9,11 @@
 
 detail::new_non_null_reference list_base::call(object const& arg_)
 {
+    union{ PyTypeObject *ptop; PyObject *pop; }pun = { &PyList_Type };
     return (detail::new_non_null_reference)
         (expect_non_null)(
             PyObject_CallFunction(
-                (PyObject*)&PyList_Type, "(O)", 
+                pun.pop, "(O)", 
                 arg_.ptr()));
 }
 
--- libs/python/src/long.cpp
+++ libs/python/src/long.cpp
@@ -8,24 +8,25 @@
 
 new_non_null_reference long_base::call(object const& arg_)
 {
+    union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyLong_Type };
     return (detail::new_non_null_reference)PyObject_CallFunction(
-        (PyObject*)&PyLong_Type, "(O)", 
-        arg_.ptr());
+        pun.pop, "(O)", arg_.ptr());
 }
 
 new_non_null_reference long_base::call(object const& arg_, object const& base)
 {
+    union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyLong_Type };
     return (detail::new_non_null_reference)PyObject_CallFunction(
-        (PyObject*)&PyLong_Type, "(OO)", 
-        arg_.ptr(), base.ptr());
+        pun.pop, "(OO)", arg_.ptr(), base.ptr());
 }
 
 long_base::long_base()
-    : object(
-        detail::new_reference(
-            PyObject_CallFunction((PyObject*)&PyLong_Type, "()"))
-        )
-{}
+{
+    union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyLong_Type };
+    object(detail::new_reference(
+            PyObject_CallFunction(pun.pop, "()")));
+    
+}
 
 long_base::long_base(object_cref arg)
     : object(long_base::call(arg))
--- libs/python/src/object/class.cpp
+++ libs/python/src/object/class.cpp
@@ -538,9 +538,11 @@
   void class_base::add_property(
     char const* name, object const& fget, char const* docstr)
   {
+      union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyProperty_Type };
+
       object property(
           (python::detail::new_reference)
-              PyObject_CallFunction((PyObject*)&PyProperty_Type, "Osss", fget.ptr(), 0, 0, docstr));
+              PyObject_CallFunction(pun.pop, "Osss", fget.ptr(), 0, 0, docstr));
       
       this->setattr(name, property);
   }
@@ -548,9 +550,11 @@
   void class_base::add_property(
     char const* name, object const& fget, object const& fset, char const* docstr)
   {
+      union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyProperty_Type };
+
       object property(
           (python::detail::new_reference)
-              PyObject_CallFunction((PyObject*)&PyProperty_Type, "OOss", fget.ptr(), fset.ptr(), 0, docstr));
+              PyObject_CallFunction(pun.pop, "OOss", fget.ptr(), fset.ptr(), 0, docstr));
       
       this->setattr(name, property);
   }
--- libs/python/src/str.cpp
+++ libs/python/src/str.cpp
@@ -8,9 +8,10 @@
 
 detail::new_reference str_base::call(object const& arg_)
 {
+    union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyString_Type };
+    
     return (detail::new_reference)PyObject_CallFunction(
-        (PyObject*)&PyString_Type, "(O)", 
-        arg_.ptr());
+        pun.pop, "(O)", arg_.ptr());
 } 
 
 str_base::str_base()
--- libs/python/src/tuple.cpp
+++ libs/python/src/tuple.cpp
@@ -8,9 +8,10 @@
 
 detail::new_reference tuple_base::call(object const& arg_)
 {
+    union { PyTypeObject *ptop; PyObject *pop; }pun = { &PyTuple_Type };
+    
     return (detail::new_reference)PyObject_CallFunction(
-        (PyObject*)&PyTuple_Type, "(O)", 
-        arg_.ptr());
+        pun.pop, "(O)", arg_.ptr());
 }
     
 tuple_base::tuple_base()

-- 
Anything whose specification is too complicated to explain easily probably
needs to be redesigned.
				David Abrahams on boost



More information about the Cplusplus-sig mailing list