From 3ce26d231433c498799bdc8fa92b70b99fb0b1a9 Mon Sep 17 00:00:00 2001 From: da-woods Date: Fri, 22 Dec 2023 12:45:07 +0000 Subject: [PATCH] Modified "pretend_to_initialize" for c++ In this case we actually have to initialize rather than just do nothing. Fixes #5278. Supercedes #5296 (I think this is better since it limits the amount of work Cython itself has to do) --- Cython/Compiler/ModuleNode.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 3014d729421..592e2473501 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -866,7 +866,24 @@ def generate_module_preamble(self, env, options, cimported_modules, metadata, co PyrexTypes.c_int_type.create_from_py_utility_code(env) code.put(Nodes.branch_prediction_macros) + + # For C, taking an address of a variable is enough to make returning it + # defined behaviour. For C++ this isn't true, and we genuinely have to + # make sure a variable is initialized. + code.putln('#if __cplusplus') + code.putln('#include ') + code.putln('template void __Pyx_pretend_to_initialize(T* ptr) {') + # In C++11 we have enough introspection to work out which types it's actually + # necessary to apply this to (non-trivial types will have been initialized by + # the definition). Below that just apply it to eveything. + code.putln('#if __cplusplus > 201103L') + code.putln('if ((std::is_trivially_default_constructible::value))') + code.putln('#endif') + code.putln('*ptr = T();') + code.putln('}') + code.putln('#else') code.putln('static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; }') + code.putln('#endif') code.putln('') code.putln('#if !CYTHON_USE_MODULE_STATE') code.putln('static PyObject *%s = NULL;' % env.module_cname)