From e12f38a38729dab3e6ac36749d25fc0bce4dbfd7 Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Sun, 29 Nov 2015 23:31:11 -0600
Subject: [PATCH] Work around older (4.8/4.9) gcc issues on Ubuntu (thanks
 @larsmans)

---
 src/c_wrapper/buffer.cpp        |  2 +-
 src/c_wrapper/command_queue.cpp | 10 +++++-----
 src/c_wrapper/command_queue.h   |  2 +-
 src/c_wrapper/context.cpp       | 10 +++++-----
 src/c_wrapper/context.h         |  2 +-
 src/c_wrapper/device.cpp        | 28 ++++++++++++++--------------
 src/c_wrapper/device.h          |  2 +-
 src/c_wrapper/error.h           |  8 ++++++++
 src/c_wrapper/event.cpp         | 18 +++++++++---------
 src/c_wrapper/event.h           |  2 +-
 src/c_wrapper/image.cpp         |  6 +++---
 src/c_wrapper/image.h           |  2 +-
 src/c_wrapper/kernel.cpp        | 24 ++++++++++++------------
 src/c_wrapper/kernel.h          |  2 +-
 src/c_wrapper/memory_map.cpp    |  4 ++--
 src/c_wrapper/memory_object.cpp | 14 +++++++-------
 src/c_wrapper/memory_object.h   |  4 ++--
 src/c_wrapper/platform.cpp      |  2 +-
 src/c_wrapper/program.cpp       | 32 ++++++++++++++++----------------
 src/c_wrapper/program.h         |  4 ++--
 src/c_wrapper/sampler.cpp       | 12 ++++++------
 src/c_wrapper/sampler.h         |  2 +-
 22 files changed, 100 insertions(+), 92 deletions(-)

diff --git a/src/c_wrapper/buffer.cpp b/src/c_wrapper/buffer.cpp
index b506b8e7..75480398 100644
--- a/src/c_wrapper/buffer.cpp
+++ b/src/c_wrapper/buffer.cpp
@@ -18,7 +18,7 @@ buffer::get_sub_region(size_t orig, size_t size, cl_mem_flags flags) const
     cl_buffer_region reg = {orig, size};
 
     auto mem = retry_mem_error([&] {
-            return pyopencl_call_guarded(clCreateSubBuffer, this, flags,
+            return pyopencl_call_guarded(clCreateSubBuffer, PYOPENCL_CL_CASTABLE_THIS, flags,
                                          CL_BUFFER_CREATE_TYPE_REGION, &reg);
         });
     return new_buffer(mem);
diff --git a/src/c_wrapper/command_queue.cpp b/src/c_wrapper/command_queue.cpp
index e56beea2..a897540a 100644
--- a/src/c_wrapper/command_queue.cpp
+++ b/src/c_wrapper/command_queue.cpp
@@ -13,7 +13,7 @@ template void print_buf<cl_command_queue>(
 
 command_queue::~command_queue()
 {
-    pyopencl_call_guarded_cleanup(clReleaseCommandQueue, this);
+    pyopencl_call_guarded_cleanup(clReleaseCommandQueue, PYOPENCL_CL_CASTABLE_THIS);
 }
 
 generic_info
@@ -22,15 +22,15 @@ command_queue::get_info(cl_uint param_name) const
     switch ((cl_command_queue_info)param_name) {
     case CL_QUEUE_CONTEXT:
         return pyopencl_get_opaque_info(context, CommandQueue,
-                                        this, param_name);
+                                        PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_QUEUE_DEVICE:
-        return pyopencl_get_opaque_info(device, CommandQueue, this, param_name);
+        return pyopencl_get_opaque_info(device, CommandQueue, PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_QUEUE_REFERENCE_COUNT:
         return pyopencl_get_int_info(cl_uint, CommandQueue,
-                                     this, param_name);
+                                     PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_QUEUE_PROPERTIES:
         return pyopencl_get_int_info(cl_command_queue_properties,
-                                     CommandQueue, this, param_name);
+                                     CommandQueue, PYOPENCL_CL_CASTABLE_THIS, param_name);
     default:
         throw clerror("CommandQueue.get_info", CL_INVALID_VALUE);
     }
diff --git a/src/c_wrapper/command_queue.h b/src/c_wrapper/command_queue.h
index 378666fa..3a7c0171 100644
--- a/src/c_wrapper/command_queue.h
+++ b/src/c_wrapper/command_queue.h
@@ -19,7 +19,7 @@ public:
         : clobj(q)
     {
         if (retain) {
-            pyopencl_call_guarded(clRetainCommandQueue, this);
+            pyopencl_call_guarded(clRetainCommandQueue, PYOPENCL_CL_CASTABLE_THIS);
         }
     }
     PYOPENCL_INLINE
diff --git a/src/c_wrapper/context.cpp b/src/c_wrapper/context.cpp
index 11f68345..0a453d0b 100644
--- a/src/c_wrapper/context.cpp
+++ b/src/c_wrapper/context.cpp
@@ -33,7 +33,7 @@ context::get_version(cl_context ctx, int *major, int *minor)
 
 context::~context()
 {
-    pyopencl_call_guarded_cleanup(clReleaseContext, this);
+    pyopencl_call_guarded_cleanup(clReleaseContext, PYOPENCL_CL_CASTABLE_THIS);
 }
 
 generic_info
@@ -42,13 +42,13 @@ context::get_info(cl_uint param_name) const
     switch ((cl_context_info)param_name) {
     case CL_CONTEXT_REFERENCE_COUNT:
         return pyopencl_get_int_info(cl_uint, Context,
-                                     this, param_name);
+                                     PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_CONTEXT_DEVICES:
         return pyopencl_get_opaque_array_info(device, Context,
-                                              this, param_name);
+                                              PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_CONTEXT_PROPERTIES: {
         auto result = pyopencl_get_vec_info(
-            cl_context_properties, Context, this, param_name);
+            cl_context_properties, Context, PYOPENCL_CL_CASTABLE_THIS, param_name);
         pyopencl_buf<generic_info> py_result(result.len() / 2);
         size_t i = 0;
         for (;i < py_result.len();i++) {
@@ -96,7 +96,7 @@ context::get_info(cl_uint param_name) const
 #if PYOPENCL_CL_VERSION >= 0x1010
     case CL_CONTEXT_NUM_DEVICES:
         return pyopencl_get_int_info(cl_uint, Context,
-                                     this, param_name);
+                                     PYOPENCL_CL_CASTABLE_THIS, param_name);
 #endif
 
     default:
diff --git a/src/c_wrapper/context.h b/src/c_wrapper/context.h
index ff94ecb1..1691035d 100644
--- a/src/c_wrapper/context.h
+++ b/src/c_wrapper/context.h
@@ -20,7 +20,7 @@ public:
         : clobj(ctx)
     {
         if (retain) {
-            pyopencl_call_guarded(clRetainContext, this);
+            pyopencl_call_guarded(clRetainContext, PYOPENCL_CL_CASTABLE_THIS);
         }
     }
     ~context();
diff --git a/src/c_wrapper/device.cpp b/src/c_wrapper/device.cpp
index c4a62a16..39ebfd0f 100644
--- a/src/c_wrapper/device.cpp
+++ b/src/c_wrapper/device.cpp
@@ -23,7 +23,7 @@ device::~device()
     }
 #if PYOPENCL_CL_VERSION >= 0x1020
     else if (m_ref_type == REF_CL_1_2) {
-        pyopencl_call_guarded_cleanup(clReleaseDevice, this);
+        pyopencl_call_guarded_cleanup(clReleaseDevice, PYOPENCL_CL_CASTABLE_THIS);
     }
 #endif
 }
@@ -32,7 +32,7 @@ generic_info
 device::get_info(cl_uint param_name) const
 {
 #define DEV_GET_INT_INF(TYPE)                                   \
-    pyopencl_get_int_info(TYPE, Device, this, param_name)
+    pyopencl_get_int_info(TYPE, Device, PYOPENCL_CL_CASTABLE_THIS, param_name)
 
     switch ((cl_device_info)param_name) {
     case CL_DEVICE_TYPE:
@@ -45,7 +45,7 @@ device::get_info(cl_uint param_name) const
         return DEV_GET_INT_INF(cl_uint);
 
     case CL_DEVICE_MAX_WORK_ITEM_SIZES:
-        return pyopencl_get_array_info(size_t, Device, this, param_name);
+        return pyopencl_get_array_info(size_t, Device, PYOPENCL_CL_CASTABLE_THIS, param_name);
 
     case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
     case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
@@ -118,10 +118,10 @@ device::get_info(cl_uint param_name) const
     case CL_DEVICE_PROFILE:
     case CL_DEVICE_VERSION:
     case CL_DEVICE_EXTENSIONS:
-        return pyopencl_get_str_info(Device, this, param_name);
+        return pyopencl_get_str_info(Device, PYOPENCL_CL_CASTABLE_THIS, param_name);
 
     case CL_DEVICE_PLATFORM:
-        return pyopencl_get_opaque_info(platform, Device, this, param_name);
+        return pyopencl_get_opaque_info(platform, Device, PYOPENCL_CL_CASTABLE_THIS, param_name);
 #if PYOPENCL_CL_VERSION >= 0x1010
     case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF:
     case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR:
@@ -136,7 +136,7 @@ device::get_info(cl_uint param_name) const
     case CL_DEVICE_HOST_UNIFIED_MEMORY: // deprecated in 2.0
         return DEV_GET_INT_INF(cl_bool);
     case CL_DEVICE_OPENCL_C_VERSION:
-        return pyopencl_get_str_info(Device, this, param_name);
+        return pyopencl_get_str_info(Device, PYOPENCL_CL_CASTABLE_THIS, param_name);
 #endif
 #ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
     case CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV:
@@ -153,21 +153,21 @@ device::get_info(cl_uint param_name) const
     case CL_DEVICE_LINKER_AVAILABLE:
         return DEV_GET_INT_INF(cl_bool);
     case CL_DEVICE_BUILT_IN_KERNELS:
-        return pyopencl_get_str_info(Device, this, param_name);
+        return pyopencl_get_str_info(Device, PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_DEVICE_IMAGE_MAX_BUFFER_SIZE:
     case CL_DEVICE_IMAGE_MAX_ARRAY_SIZE:
         return DEV_GET_INT_INF(size_t);
     case CL_DEVICE_PARENT_DEVICE:
-        return pyopencl_get_opaque_info(device, Device, this, param_name);
+        return pyopencl_get_opaque_info(device, Device, PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_DEVICE_PARTITION_MAX_SUB_DEVICES:
         return DEV_GET_INT_INF(cl_uint);
     case CL_DEVICE_PARTITION_TYPE:
     case CL_DEVICE_PARTITION_PROPERTIES:
         return pyopencl_get_array_info(cl_device_partition_property,
-                                       Device, this, param_name);
+                                       Device, PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_DEVICE_PARTITION_AFFINITY_DOMAIN:
         return pyopencl_get_array_info(cl_device_affinity_domain,
-                                       Device, this, param_name);
+                                       Device, PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_DEVICE_REFERENCE_COUNT:
         return DEV_GET_INT_INF(cl_uint);
     case CL_DEVICE_PREFERRED_INTEROP_USER_SYNC:
@@ -225,12 +225,12 @@ device::get_info(cl_uint param_name) const
         */
 #ifdef CL_DEVICE_BOARD_NAME_AMD
     case CL_DEVICE_BOARD_NAME_AMD: ;
-        return pyopencl_get_str_info(Device, this, param_name);
+        return pyopencl_get_str_info(Device, PYOPENCL_CL_CASTABLE_THIS, param_name);
 #endif
 #ifdef CL_DEVICE_GLOBAL_FREE_MEMORY_AMD
     case CL_DEVICE_GLOBAL_FREE_MEMORY_AMD:
         return pyopencl_get_array_info(size_t, Device,
-                                       this, param_name);
+                                       PYOPENCL_CL_CASTABLE_THIS, param_name);
 #endif
 #ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD
     case CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD:
@@ -277,10 +277,10 @@ device::create_sub_devices(const cl_device_partition_property *props)
 {
     // TODO debug print props
     cl_uint num_devices;
-    pyopencl_call_guarded(clCreateSubDevices, this, props, 0, nullptr,
+    pyopencl_call_guarded(clCreateSubDevices, PYOPENCL_CL_CASTABLE_THIS, props, 0, nullptr,
                           buf_arg(num_devices));
     pyopencl_buf<cl_device_id> devices(num_devices);
-    pyopencl_call_guarded(clCreateSubDevices, this, props, devices,
+    pyopencl_call_guarded(clCreateSubDevices, PYOPENCL_CL_CASTABLE_THIS, props, devices,
                           buf_arg(num_devices));
     return buf_to_base<device>(devices, true, device::REF_CL_1_2);
 }
diff --git a/src/c_wrapper/device.h b/src/c_wrapper/device.h
index a74ce5a5..a14a9468 100644
--- a/src/c_wrapper/device.h
+++ b/src/c_wrapper/device.h
@@ -33,7 +33,7 @@ public:
             }
 #if PYOPENCL_CL_VERSION >= 0x1020
             else if (ref_type == REF_CL_1_2) {
-                pyopencl_call_guarded(clRetainDevice, this);
+                pyopencl_call_guarded(clRetainDevice, PYOPENCL_CL_CASTABLE_THIS);
             }
 #endif
 
diff --git a/src/c_wrapper/error.h b/src/c_wrapper/error.h
index 5e483698..3a7ed85e 100644
--- a/src/c_wrapper/error.h
+++ b/src/c_wrapper/error.h
@@ -14,6 +14,14 @@
 
 // {{{ error
 
+// See https://github.com/pyopencl/pyopencl/pull/83
+#if GCC_VERSION > 50200
+#define PYOPENCL_CL_CASTABLE_THIS this
+#else
+#define PYOPENCL_CL_CASTABLE_THIS data()
+#endif
+
+
 class clerror : public std::runtime_error {
 private:
     const char *m_routine;
diff --git a/src/c_wrapper/event.cpp b/src/c_wrapper/event.cpp
index 63c6daa7..6faf2b58 100644
--- a/src/c_wrapper/event.cpp
+++ b/src/c_wrapper/event.cpp
@@ -40,7 +40,7 @@ event::event(cl_event event, bool retain, event_private *p)
 {
     if (retain) {
         try {
-            pyopencl_call_guarded(clRetainEvent, this);
+            pyopencl_call_guarded(clRetainEvent, PYOPENCL_CL_CASTABLE_THIS);
         } catch (...) {
             m_p->call_finish();
             delete m_p;
@@ -106,7 +106,7 @@ event::release_private() noexcept
 event::~event()
 {
     release_private();
-    pyopencl_call_guarded_cleanup(clReleaseEvent, this);
+    pyopencl_call_guarded_cleanup(clReleaseEvent, PYOPENCL_CL_CASTABLE_THIS);
 }
 
 generic_info
@@ -114,17 +114,17 @@ event::get_info(cl_uint param_name) const
 {
     switch ((cl_event_info)param_name) {
     case CL_EVENT_COMMAND_QUEUE:
-        return pyopencl_get_opaque_info(command_queue, Event, this, param_name);
+        return pyopencl_get_opaque_info(command_queue, Event, PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_EVENT_COMMAND_TYPE:
         return pyopencl_get_int_info(cl_command_type, Event,
-                                     this, param_name);
+                                     PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_EVENT_COMMAND_EXECUTION_STATUS:
-        return pyopencl_get_int_info(cl_int, Event, this, param_name);
+        return pyopencl_get_int_info(cl_int, Event, PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_EVENT_REFERENCE_COUNT:
-        return pyopencl_get_int_info(cl_uint, Event, this, param_name);
+        return pyopencl_get_int_info(cl_uint, Event, PYOPENCL_CL_CASTABLE_THIS, param_name);
 #if PYOPENCL_CL_VERSION >= 0x1010
     case CL_EVENT_CONTEXT:
-        return pyopencl_get_opaque_info(context, Event, this, param_name);
+        return pyopencl_get_opaque_info(context, Event, PYOPENCL_CL_CASTABLE_THIS, param_name);
 #endif
 
     default:
@@ -140,7 +140,7 @@ event::get_profiling_info(cl_profiling_info param) const
     case CL_PROFILING_COMMAND_SUBMIT:
     case CL_PROFILING_COMMAND_START:
     case CL_PROFILING_COMMAND_END:
-        return pyopencl_get_int_info(cl_ulong, EventProfiling, this, param);
+        return pyopencl_get_int_info(cl_ulong, EventProfiling, PYOPENCL_CL_CASTABLE_THIS, param);
     default:
         throw clerror("Event.get_profiling_info", CL_INVALID_VALUE);
     }
@@ -195,7 +195,7 @@ public:
     PYOPENCL_INLINE void
     set_status(cl_int status)
     {
-        pyopencl_call_guarded(clSetUserEventStatus, this, status);
+        pyopencl_call_guarded(clSetUserEventStatus, PYOPENCL_CL_CASTABLE_THIS, status);
     }
 };
 #endif
diff --git a/src/c_wrapper/event.h b/src/c_wrapper/event.h
index 7c3b4852..3d6c8769 100644
--- a/src/c_wrapper/event.h
+++ b/src/c_wrapper/event.h
@@ -39,7 +39,7 @@ public:
         auto func = new rm_ref_t<Func>(std::forward<Func>(_func));
         try {
             pyopencl_call_guarded(
-                clSetEventCallback, this, type,
+                clSetEventCallback, PYOPENCL_CL_CASTABLE_THIS, type,
                 [] (cl_event, cl_int status, void *data) {
                     rm_ref_t<Func> *func = static_cast<rm_ref_t<Func>*>(data);
                     std::thread t([func, status] () {
diff --git a/src/c_wrapper/image.cpp b/src/c_wrapper/image.cpp
index 77552858..427f1e34 100644
--- a/src/c_wrapper/image.cpp
+++ b/src/c_wrapper/image.cpp
@@ -17,7 +17,7 @@ image::get_image_info(cl_image_info param) const
 {
     switch (param) {
     case CL_IMAGE_FORMAT:
-        return pyopencl_get_int_info(cl_image_format, Image, this, param);
+        return pyopencl_get_int_info(cl_image_format, Image, PYOPENCL_CL_CASTABLE_THIS, param);
     case CL_IMAGE_ELEMENT_SIZE:
     case CL_IMAGE_ROW_PITCH:
     case CL_IMAGE_SLICE_PITCH:
@@ -27,7 +27,7 @@ image::get_image_info(cl_image_info param) const
 #if PYOPENCL_CL_VERSION >= 0x1020
     case CL_IMAGE_ARRAY_SIZE:
 #endif
-        return pyopencl_get_int_info(size_t, Image, this, param);
+        return pyopencl_get_int_info(size_t, Image, PYOPENCL_CL_CASTABLE_THIS, param);
 
 #if PYOPENCL_CL_VERSION >= 0x1020
         // TODO:
@@ -44,7 +44,7 @@ image::get_image_info(cl_image_info param) const
         //      }
     case CL_IMAGE_NUM_MIP_LEVELS:
     case CL_IMAGE_NUM_SAMPLES:
-        return pyopencl_get_int_info(cl_uint, Image, this, param);
+        return pyopencl_get_int_info(cl_uint, Image, PYOPENCL_CL_CASTABLE_THIS, param);
 #endif
     default:
         throw clerror("Image.get_image_info", CL_INVALID_VALUE);
diff --git a/src/c_wrapper/image.h b/src/c_wrapper/image.h
index 55520f88..7d29909c 100644
--- a/src/c_wrapper/image.h
+++ b/src/c_wrapper/image.h
@@ -19,7 +19,7 @@ public:
     format()
     {
         if (!m_format.image_channel_data_type) {
-            pyopencl_call_guarded(clGetImageInfo, this, CL_IMAGE_FORMAT,
+            pyopencl_call_guarded(clGetImageInfo, PYOPENCL_CL_CASTABLE_THIS, CL_IMAGE_FORMAT,
                                   size_arg(m_format), nullptr);
         }
         return m_format;
diff --git a/src/c_wrapper/kernel.cpp b/src/c_wrapper/kernel.cpp
index 80ab8c5a..9c268ed6 100644
--- a/src/c_wrapper/kernel.cpp
+++ b/src/c_wrapper/kernel.cpp
@@ -16,7 +16,7 @@ template void print_buf<cl_kernel>(std::ostream&, const cl_kernel*,
 
 kernel::~kernel()
 {
-    pyopencl_call_guarded_cleanup(clReleaseKernel, this);
+    pyopencl_call_guarded_cleanup(clReleaseKernel, PYOPENCL_CL_CASTABLE_THIS);
 }
 
 generic_info
@@ -24,17 +24,17 @@ kernel::get_info(cl_uint param) const
 {
     switch ((cl_kernel_info)param) {
     case CL_KERNEL_FUNCTION_NAME:
-        return pyopencl_get_str_info(Kernel, this, param);
+        return pyopencl_get_str_info(Kernel, PYOPENCL_CL_CASTABLE_THIS, param);
     case CL_KERNEL_NUM_ARGS:
     case CL_KERNEL_REFERENCE_COUNT:
-        return pyopencl_get_int_info(cl_uint, Kernel, this, param);
+        return pyopencl_get_int_info(cl_uint, Kernel, PYOPENCL_CL_CASTABLE_THIS, param);
     case CL_KERNEL_CONTEXT:
-        return pyopencl_get_opaque_info(context, Kernel, this, param);
+        return pyopencl_get_opaque_info(context, Kernel, PYOPENCL_CL_CASTABLE_THIS, param);
     case CL_KERNEL_PROGRAM:
-        return pyopencl_get_opaque_info(program, Kernel, this, param);
+        return pyopencl_get_opaque_info(program, Kernel, PYOPENCL_CL_CASTABLE_THIS, param);
 #if PYOPENCL_CL_VERSION >= 0x1020
     case CL_KERNEL_ATTRIBUTES:
-        return pyopencl_get_str_info(Kernel, this, param);
+        return pyopencl_get_str_info(Kernel, PYOPENCL_CL_CASTABLE_THIS, param);
 #endif
     default:
         throw clerror("Kernel.get_info", CL_INVALID_VALUE);
@@ -50,16 +50,16 @@ kernel::get_work_group_info(cl_kernel_work_group_info param,
     case CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE:
 #endif
     case CL_KERNEL_WORK_GROUP_SIZE:
-        return pyopencl_get_int_info(size_t, KernelWorkGroup, this, dev, param);
+        return pyopencl_get_int_info(size_t, KernelWorkGroup, PYOPENCL_CL_CASTABLE_THIS, dev, param);
     case CL_KERNEL_COMPILE_WORK_GROUP_SIZE:
         return pyopencl_get_array_info(size_t, KernelWorkGroup,
-                                       this, dev, param);
+                                       PYOPENCL_CL_CASTABLE_THIS, dev, param);
     case CL_KERNEL_LOCAL_MEM_SIZE:
 #if PYOPENCL_CL_VERSION >= 0x1010
     case CL_KERNEL_PRIVATE_MEM_SIZE:
 #endif
         return pyopencl_get_int_info(cl_ulong, KernelWorkGroup,
-                                     this, dev, param);
+                                     PYOPENCL_CL_CASTABLE_THIS, dev, param);
     default:
         throw clerror("Kernel.get_work_group_info", CL_INVALID_VALUE);
     }
@@ -72,16 +72,16 @@ kernel::get_arg_info(cl_uint idx, cl_kernel_arg_info param) const
     switch (param) {
     case CL_KERNEL_ARG_ADDRESS_QUALIFIER:
         return pyopencl_get_int_info(cl_kernel_arg_address_qualifier,
-                                     KernelArg, this, idx, param);
+                                     KernelArg, PYOPENCL_CL_CASTABLE_THIS, idx, param);
     case CL_KERNEL_ARG_ACCESS_QUALIFIER:
         return pyopencl_get_int_info(cl_kernel_arg_access_qualifier,
-                                     KernelArg, this, idx, param);
+                                     KernelArg, PYOPENCL_CL_CASTABLE_THIS, idx, param);
     case CL_KERNEL_ARG_TYPE_QUALIFIER:
         return pyopencl_get_int_info(cl_kernel_arg_type_qualifier,
                                      KernelArg, this, idx, param);
     case CL_KERNEL_ARG_TYPE_NAME:
     case CL_KERNEL_ARG_NAME:
-        return pyopencl_get_str_info(KernelArg, this, idx, param);
+        return pyopencl_get_str_info(KernelArg, PYOPENCL_CL_CASTABLE_THIS, idx, param);
     default:
         throw clerror("Kernel.get_arg_info", CL_INVALID_VALUE);
     }
diff --git a/src/c_wrapper/kernel.h b/src/c_wrapper/kernel.h
index 4a1b332a..5db1a0cc 100644
--- a/src/c_wrapper/kernel.h
+++ b/src/c_wrapper/kernel.h
@@ -21,7 +21,7 @@ public:
         : clobj(knl)
     {
         if (retain) {
-            pyopencl_call_guarded(clRetainKernel, this);
+            pyopencl_call_guarded(clRetainKernel, PYOPENCL_CL_CASTABLE_THIS);
         }
     }
     ~kernel();
diff --git a/src/c_wrapper/memory_map.cpp b/src/c_wrapper/memory_map.cpp
index f9014dcd..068274df 100644
--- a/src/c_wrapper/memory_map.cpp
+++ b/src/c_wrapper/memory_map.cpp
@@ -14,7 +14,7 @@ memory_map::~memory_map()
     if (!m_valid.exchange(false))
         return;
     pyopencl_call_guarded_cleanup(clEnqueueUnmapMemObject, m_queue,
-                                  m_mem, this, 0, nullptr, nullptr);
+                                  m_mem, PYOPENCL_CL_CASTABLE_THIS, 0, nullptr, nullptr);
 }
 
 void
@@ -28,7 +28,7 @@ memory_map::release(clobj_t *evt, const command_queue *queue,
     const auto wait_for = buf_from_class<event>(_wait_for, num_wait_for);
     queue = queue ? queue : &m_queue;
     pyopencl_call_guarded(clEnqueueUnmapMemObject, queue,
-                          m_mem, this, wait_for, event_out(evt));
+                          m_mem, PYOPENCL_CL_CASTABLE_THIS, wait_for, event_out(evt));
 }
 
 generic_info
diff --git a/src/c_wrapper/memory_object.cpp b/src/c_wrapper/memory_object.cpp
index 98e8fbe5..de722420 100644
--- a/src/c_wrapper/memory_object.cpp
+++ b/src/c_wrapper/memory_object.cpp
@@ -15,12 +15,12 @@ memory_object::get_info(cl_uint param_name) const
     switch ((cl_mem_info)param_name) {
     case CL_MEM_TYPE:
         return pyopencl_get_int_info(cl_mem_object_type, MemObject,
-                                     this, param_name);
+                                     PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_MEM_FLAGS:
         return pyopencl_get_int_info(cl_mem_flags, MemObject,
-                                     this, param_name);
+                                     PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_MEM_SIZE:
-        return pyopencl_get_int_info(size_t, MemObject, this, param_name);
+        return pyopencl_get_int_info(size_t, MemObject, PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_MEM_HOST_PTR:
         throw clerror("MemoryObject.get_info", CL_INVALID_VALUE,
                       "Use MemoryObject.get_host_array to get "
@@ -28,9 +28,9 @@ memory_object::get_info(cl_uint param_name) const
     case CL_MEM_MAP_COUNT:
     case CL_MEM_REFERENCE_COUNT:
         return pyopencl_get_int_info(cl_uint, MemObject,
-                                     this, param_name);
+                                     PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_MEM_CONTEXT:
-        return pyopencl_get_opaque_info(context, MemObject, this, param_name);
+        return pyopencl_get_opaque_info(context, MemObject, PYOPENCL_CL_CASTABLE_THIS, param_name);
 
 #if PYOPENCL_CL_VERSION >= 0x1010
         // TODO
@@ -47,7 +47,7 @@ memory_object::get_info(cl_uint param_name) const
         //        return create_mem_object_wrapper(param_value);
         //      }
     case CL_MEM_OFFSET:
-        return pyopencl_get_int_info(size_t, MemObject, this, param_name);
+        return pyopencl_get_int_info(size_t, MemObject, PYOPENCL_CL_CASTABLE_THIS, param_name);
 #endif
 #if PYOPENCL_CL_VERSION >= 0x2000
     case CL_MEM_USES_SVM_POINTER:
@@ -63,7 +63,7 @@ memory_object::~memory_object()
 {
     if (!m_valid.exchange(false))
         return;
-    pyopencl_call_guarded_cleanup(clReleaseMemObject, this);
+    pyopencl_call_guarded_cleanup(clReleaseMemObject, PYOPENCL_CL_CASTABLE_THIS);
 }
 
 // c wrapper
diff --git a/src/c_wrapper/memory_object.h b/src/c_wrapper/memory_object.h
index a56972e1..635dc470 100644
--- a/src/c_wrapper/memory_object.h
+++ b/src/c_wrapper/memory_object.h
@@ -21,7 +21,7 @@ public:
         : clobj(mem), m_valid(true)
     {
         if (retain) {
-            pyopencl_call_guarded(clRetainMemObject, this);
+            pyopencl_call_guarded(clRetainMemObject, PYOPENCL_CL_CASTABLE_THIS);
         }
     }
     PYOPENCL_INLINE
@@ -37,7 +37,7 @@ public:
             throw clerror("MemoryObject.release", CL_INVALID_VALUE,
                           "trying to double-unref mem object");
         }
-        pyopencl_call_guarded(clReleaseMemObject, this);
+        pyopencl_call_guarded(clReleaseMemObject, PYOPENCL_CL_CASTABLE_THIS);
     }
 #if 0
     PYOPENCL_USE_RESULT size_t
diff --git a/src/c_wrapper/platform.cpp b/src/c_wrapper/platform.cpp
index f75f4049..13b890f1 100644
--- a/src/c_wrapper/platform.cpp
+++ b/src/c_wrapper/platform.cpp
@@ -22,7 +22,7 @@ platform::get_info(cl_uint param_name) const
 #if !(defined(CL_PLATFORM_NVIDIA) && CL_PLATFORM_NVIDIA == 0x3001)
     case CL_PLATFORM_EXTENSIONS:
 #endif
-        return pyopencl_get_str_info(Platform, this, param_name);
+        return pyopencl_get_str_info(Platform, PYOPENCL_CL_CASTABLE_THIS, param_name);
     default:
         throw clerror("Platform.get_info", CL_INVALID_VALUE);
     }
diff --git a/src/c_wrapper/program.cpp b/src/c_wrapper/program.cpp
index 6aac02f1..39bf829b 100644
--- a/src/c_wrapper/program.cpp
+++ b/src/c_wrapper/program.cpp
@@ -18,7 +18,7 @@ new_program(cl_program prog, program_kind_type progkind=KND_UNKNOWN)
 
 program::~program()
 {
-    pyopencl_call_guarded_cleanup(clReleaseProgram, this);
+    pyopencl_call_guarded_cleanup(clReleaseProgram, PYOPENCL_CL_CASTABLE_THIS);
 }
 
 generic_info
@@ -26,25 +26,25 @@ program::get_info(cl_uint param) const
 {
     switch ((cl_program_info)param) {
     case CL_PROGRAM_CONTEXT:
-        return pyopencl_get_opaque_info(context, Program, this, param);
+        return pyopencl_get_opaque_info(context, Program, PYOPENCL_CL_CASTABLE_THIS, param);
     case CL_PROGRAM_REFERENCE_COUNT:
     case CL_PROGRAM_NUM_DEVICES:
-        return pyopencl_get_int_info(cl_uint, Program, this, param);
+        return pyopencl_get_int_info(cl_uint, Program, PYOPENCL_CL_CASTABLE_THIS, param);
     case CL_PROGRAM_DEVICES:
-        return pyopencl_get_opaque_array_info(device, Program, this, param);
+        return pyopencl_get_opaque_array_info(device, Program, PYOPENCL_CL_CASTABLE_THIS, param);
     case CL_PROGRAM_SOURCE:
-        return pyopencl_get_str_info(Program, this, param);
+        return pyopencl_get_str_info(Program, PYOPENCL_CL_CASTABLE_THIS, param);
     case CL_PROGRAM_BINARY_SIZES:
-        return pyopencl_get_array_info(size_t, Program, this, param);
+        return pyopencl_get_array_info(size_t, Program, PYOPENCL_CL_CASTABLE_THIS, param);
     case CL_PROGRAM_BINARIES: {
-        auto sizes = pyopencl_get_vec_info(size_t, Program, this,
+        auto sizes = pyopencl_get_vec_info(size_t, Program, PYOPENCL_CL_CASTABLE_THIS,
                                            CL_PROGRAM_BINARY_SIZES);
         pyopencl_buf<char*> result_ptrs(sizes.len());
         for (size_t i  = 0;i < sizes.len();i++) {
             result_ptrs[i] = (char*)malloc(sizes[i]);
         }
         try {
-            pyopencl_call_guarded(clGetProgramInfo, this, CL_PROGRAM_BINARIES,
+            pyopencl_call_guarded(clGetProgramInfo, PYOPENCL_CL_CASTABLE_THIS, CL_PROGRAM_BINARIES,
                                   sizes.len() * sizeof(char*),
                                   result_ptrs.get(), nullptr);
         } catch (...) {
@@ -65,9 +65,9 @@ program::get_info(cl_uint param) const
 
 #if PYOPENCL_CL_VERSION >= 0x1020
     case CL_PROGRAM_NUM_KERNELS:
-        return pyopencl_get_int_info(size_t, Program, this, param);
+        return pyopencl_get_int_info(size_t, Program, PYOPENCL_CL_CASTABLE_THIS, param);
     case CL_PROGRAM_KERNEL_NAMES:
-        return pyopencl_get_str_info(Program, this, param);
+        return pyopencl_get_str_info(Program, PYOPENCL_CL_CASTABLE_THIS, param);
 #endif
     default:
         throw clerror("Program.get_info", CL_INVALID_VALUE);
@@ -80,14 +80,14 @@ program::get_build_info(const device *dev, cl_program_build_info param) const
     switch (param) {
     case CL_PROGRAM_BUILD_STATUS:
         return pyopencl_get_int_info(cl_build_status, ProgramBuild,
-                                     this, dev, param);
+                                     PYOPENCL_CL_CASTABLE_THIS, dev, param);
     case CL_PROGRAM_BUILD_OPTIONS:
     case CL_PROGRAM_BUILD_LOG:
-        return pyopencl_get_str_info(ProgramBuild, this, dev, param);
+        return pyopencl_get_str_info(ProgramBuild, PYOPENCL_CL_CASTABLE_THIS, dev, param);
 #if PYOPENCL_CL_VERSION >= 0x1020
     case CL_PROGRAM_BINARY_TYPE:
         return pyopencl_get_int_info(cl_program_binary_type, ProgramBuild,
-                                     this, dev, param);
+                                     PYOPENCL_CL_CASTABLE_THIS, dev, param);
 #endif
 #if PYOPENCL_CL_VERSION >= 0x2000
     case CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE:
@@ -107,7 +107,7 @@ program::compile(const char *opts, const clobj_t *_devs, size_t num_devs,
 {
     const auto devs = buf_from_class<device>(_devs, num_devs);
     const auto prgs = buf_from_class<program>(_prgs, num_hdrs);
-    pyopencl_call_guarded(clCompileProgram, this, devs, opts, prgs,
+    pyopencl_call_guarded(clCompileProgram, PYOPENCL_CL_CASTABLE_THIS, devs, opts, prgs,
                           buf_arg(names, num_hdrs), nullptr, nullptr);
 }
 #endif
@@ -116,10 +116,10 @@ pyopencl_buf<clobj_t>
 program::all_kernels()
 {
     cl_uint num_knls;
-    pyopencl_call_guarded(clCreateKernelsInProgram, this, 0, nullptr,
+    pyopencl_call_guarded(clCreateKernelsInProgram, PYOPENCL_CL_CASTABLE_THIS, 0, nullptr,
                           buf_arg(num_knls));
     pyopencl_buf<cl_kernel> knls(num_knls);
-    pyopencl_call_guarded(clCreateKernelsInProgram, this, knls,
+    pyopencl_call_guarded(clCreateKernelsInProgram, PYOPENCL_CL_CASTABLE_THIS, knls,
                           buf_arg(num_knls));
     return buf_to_base<kernel>(knls, true);
 }
diff --git a/src/c_wrapper/program.h b/src/c_wrapper/program.h
index eef07c12..63d2fc76 100644
--- a/src/c_wrapper/program.h
+++ b/src/c_wrapper/program.h
@@ -25,7 +25,7 @@ public:
         : clobj(prog), m_program_kind(progkind)
     {
         if (retain) {
-            pyopencl_call_guarded(clRetainProgram, this);
+            pyopencl_call_guarded(clRetainProgram, PYOPENCL_CL_CASTABLE_THIS);
         }
     }
     ~program();
@@ -37,7 +37,7 @@ public:
     PYOPENCL_USE_RESULT pyopencl_buf<cl_device_id>
     get_info__devices() const
     {
-        return pyopencl_get_vec_info(cl_device_id, Program, this,
+        return pyopencl_get_vec_info(cl_device_id, Program, PYOPENCL_CL_CASTABLE_THIS,
                                      CL_PROGRAM_DEVICES);
     }
     generic_info get_info(cl_uint param_name) const;
diff --git a/src/c_wrapper/sampler.cpp b/src/c_wrapper/sampler.cpp
index ee2e90cf..b373c783 100644
--- a/src/c_wrapper/sampler.cpp
+++ b/src/c_wrapper/sampler.cpp
@@ -10,7 +10,7 @@ template void print_buf<cl_sampler>(std::ostream&, const cl_sampler*,
 
 sampler::~sampler()
 {
-    pyopencl_call_guarded_cleanup(clReleaseSampler, this);
+    pyopencl_call_guarded_cleanup(clReleaseSampler, PYOPENCL_CL_CASTABLE_THIS);
 }
 
 generic_info
@@ -18,16 +18,16 @@ sampler::get_info(cl_uint param_name) const
 {
     switch ((cl_sampler_info)param_name) {
     case CL_SAMPLER_REFERENCE_COUNT:
-        return pyopencl_get_int_info(cl_uint, Sampler, this, param_name);
+        return pyopencl_get_int_info(cl_uint, Sampler, PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_SAMPLER_CONTEXT:
-        return pyopencl_get_opaque_info(context, Sampler, this, param_name);
+        return pyopencl_get_opaque_info(context, Sampler, PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_SAMPLER_ADDRESSING_MODE:
         return pyopencl_get_int_info(cl_addressing_mode, Sampler,
-                                     this, param_name);
+                                     PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_SAMPLER_FILTER_MODE:
-        return pyopencl_get_int_info(cl_filter_mode, Sampler, this, param_name);
+        return pyopencl_get_int_info(cl_filter_mode, Sampler, PYOPENCL_CL_CASTABLE_THIS, param_name);
     case CL_SAMPLER_NORMALIZED_COORDS:
-        return pyopencl_get_int_info(cl_bool, Sampler, this, param_name);
+        return pyopencl_get_int_info(cl_bool, Sampler, PYOPENCL_CL_CASTABLE_THIS, param_name);
 
 #if PYOPENCL_CL_VERSION >= 0x2000
     // TODO: MIP_FILTER_MODE, LOD_MIN, LOD_MAX
diff --git a/src/c_wrapper/sampler.h b/src/c_wrapper/sampler.h
index 0f41eaac..404b82e5 100644
--- a/src/c_wrapper/sampler.h
+++ b/src/c_wrapper/sampler.h
@@ -19,7 +19,7 @@ public:
         : clobj(samp)
     {
         if (retain) {
-            pyopencl_call_guarded(clRetainSampler, this);
+            pyopencl_call_guarded(clRetainSampler, PYOPENCL_CL_CASTABLE_THIS);
         }
     }
     ~sampler();
-- 
GitLab