From 7e3af05d99a67da1bb5a487952a76813f2d5ccfc Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 2 Aug 2021 12:41:47 -0700 Subject: [PATCH 01/18] Removing pragma for GCC -Wattributes, fixing forward declarations. --- include/pybind11/detail/common.h | 7 +------ include/pybind11/pybind11.h | 10 ---------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index cc24a52fd3..c68ade2a45 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -99,12 +99,7 @@ # endif #endif -// The PYBIND11_NOINLINE macro is for function DEFINITIONS. -// In contrast, FORWARD DECLARATIONS should never use this macro: -// https://stackoverflow.com/questions/9317473/forward-declaration-of-inline-functions -#if defined(PYBIND11_NOINLINE_DISABLED) // Option for maximum portability and experimentation. -# define PYBIND11_NOINLINE inline -#elif defined(_MSC_VER) +#if defined(_MSC_VER) # define PYBIND11_NOINLINE __declspec(noinline) inline #else # define PYBIND11_NOINLINE __attribute__ ((noinline)) inline diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 20df6a01fd..a337017ed8 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -10,11 +10,6 @@ #pragma once -#if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wattributes" -#endif - #include "attr.h" #include "gil.h" #include "options.h" @@ -1874,7 +1869,6 @@ template class enum_ : public class_ { PYBIND11_NAMESPACE_BEGIN(detail) - PYBIND11_NOINLINE void keep_alive_impl(handle nurse, handle patient) { if (!nurse || !patient) pybind11_fail("Could not activate keep_alive!"); @@ -2383,7 +2377,3 @@ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) #if defined(__GNUC__) && __GNUC__ == 7 # pragma GCC diagnostic pop // -Wnoexcept-type #endif - -#if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) -# pragma GCC diagnostic pop -#endif From 2cb5d65d9c7b60fffeb2e867f8067880ac86965d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 2 Aug 2021 13:52:36 -0700 Subject: [PATCH 02/18] Introducing PYBIND11_NOINLINE_FWD to deal with CUDA, GCC7, GCC8. --- include/pybind11/attr.h | 6 ++-- include/pybind11/detail/common.h | 15 ++++++--- include/pybind11/detail/internals.h | 6 ++-- include/pybind11/detail/type_caster_base.h | 38 +++++++++++----------- include/pybind11/detail/typeid.h | 2 +- include/pybind11/gil.h | 10 +++--- include/pybind11/numpy.h | 4 +-- include/pybind11/pybind11.h | 16 ++++----- include/pybind11/pytypes.h | 4 +-- 9 files changed, 53 insertions(+), 48 deletions(-) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index ab1fe80446..36a4343400 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -124,7 +124,7 @@ enum op_id : int; enum op_type : int; struct undefined_t; template struct op_; -void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); +PYBIND11_NOINLINE_FWD void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); /// Internal data structure which holds metadata about a keyword argument struct argument_record { @@ -220,7 +220,7 @@ struct function_record { /// Special data structure which (temporarily) holds metadata about a bound class struct type_record { - PYBIND11_NOINLINE type_record() + PYBIND11_NOINLINE_DCL type_record() : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), default_holder(true), module_local(false), is_final(false) { } @@ -278,7 +278,7 @@ struct type_record { /// Is the class inheritable from python classes? bool is_final : 1; - PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) { + PYBIND11_NOINLINE_DCL void add_base(const std::type_info &base, void *(*caster)(void *)) { auto base_info = detail::get_type_info(base, false); if (!base_info) { std::string tname(base.name()); diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index c68ade2a45..5fdb3cdc8c 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -99,10 +99,15 @@ # endif #endif -#if defined(_MSC_VER) -# define PYBIND11_NOINLINE __declspec(noinline) inline +#if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) +# define PYBIND11_NOINLINE_DCL inline +# define PYBIND11_NOINLINE_FWD inline +#elif defined(_MSC_VER) +# define PYBIND11_NOINLINE_DCL __declspec(noinline) inline +# define PYBIND11_NOINLINE_FWD #else -# define PYBIND11_NOINLINE __attribute__ ((noinline)) inline +# define PYBIND11_NOINLINE_DCL __attribute__ ((noinline)) inline +# define PYBIND11_NOINLINE_FWD #endif #if defined(__MINGW32__) @@ -778,8 +783,8 @@ PYBIND11_RUNTIME_EXCEPTION(import_error, PyExc_ImportError) PYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or handle::call fail due to a type casting error PYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally -[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } -[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const std::string &reason) { throw std::runtime_error(reason); } +[[noreturn]] PYBIND11_NOINLINE_DCL void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } +[[noreturn]] PYBIND11_NOINLINE_DCL void pybind11_fail(const std::string &reason) { throw std::runtime_error(reason); } template struct format_descriptor { }; diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index b177801a11..eac3079c68 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -257,7 +257,7 @@ inline void translate_local_exception(std::exception_ptr p) { #endif /// Return a reference to the current `internals` data -PYBIND11_NOINLINE internals &get_internals() { +PYBIND11_NOINLINE_DCL internals &get_internals() { auto **&internals_pp = get_internals_pp(); if (internals_pp && *internals_pp) return **internals_pp; @@ -352,14 +352,14 @@ PYBIND11_NAMESPACE_END(detail) /// Returns a named pointer that is shared among all extension modules (using the same /// pybind11 version) running in the current interpreter. Names starting with underscores /// are reserved for internal usage. Returns `nullptr` if no matching entry was found. -PYBIND11_NOINLINE void *get_shared_data(const std::string &name) { +PYBIND11_NOINLINE_DCL void *get_shared_data(const std::string &name) { auto &internals = detail::get_internals(); auto it = internals.shared_data.find(name); return it != internals.shared_data.end() ? it->second : nullptr; } /// Set the shared data that can be later recovered by `get_shared_data()`. -PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) { +PYBIND11_NOINLINE_DCL void *set_shared_data(const std::string &name, void *data) { detail::get_internals().shared_data[name] = data; return data; } diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index 14cb27cad2..eae5a12f4a 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -54,7 +54,7 @@ class loader_life_support { /// This can only be used inside a pybind11-bound function, either by `argument_loader` /// at argument preparation time or by `py::cast()` at execution time. - PYBIND11_NOINLINE static void add_patient(handle h) { + PYBIND11_NOINLINE_DCL static void add_patient(handle h) { auto &stack = get_internals().loader_patient_stack; if (stack.empty()) throw cast_error("When called outside a bound function, py::cast() cannot " @@ -81,7 +81,7 @@ class loader_life_support { inline std::pair all_type_info_get_cache(PyTypeObject *type); // Populates a just-created cache entry. -PYBIND11_NOINLINE void all_type_info_populate(PyTypeObject *t, std::vector &bases) { +PYBIND11_NOINLINE_DCL void all_type_info_populate(PyTypeObject *t, std::vector &bases) { std::vector check; for (handle parent : reinterpret_borrow(t->tp_bases)) check.push_back((PyTypeObject *) parent.ptr()); @@ -150,7 +150,7 @@ inline const std::vector &all_type_info(PyTypeObject *type) * ancestors are pybind11-registered. Throws an exception if there are multiple bases--use * `all_type_info` instead if you want to support multiple bases. */ -PYBIND11_NOINLINE detail::type_info* get_type_info(PyTypeObject *type) { +PYBIND11_NOINLINE_DCL detail::type_info* get_type_info(PyTypeObject *type) { auto &bases = all_type_info(type); if (bases.empty()) return nullptr; @@ -176,7 +176,7 @@ inline detail::type_info *get_global_type_info(const std::type_index &tp) { } /// Return the type info for a given C++ type; on lookup failure can either throw or return nullptr. -PYBIND11_NOINLINE detail::type_info *get_type_info(const std::type_index &tp, +PYBIND11_NOINLINE_DCL detail::type_info *get_type_info(const std::type_index &tp, bool throw_if_missing = false) { if (auto ltype = get_local_type_info(tp)) return ltype; @@ -191,13 +191,13 @@ PYBIND11_NOINLINE detail::type_info *get_type_info(const std::type_index &tp, return nullptr; } -PYBIND11_NOINLINE handle get_type_handle(const std::type_info &tp, bool throw_if_missing) { +PYBIND11_NOINLINE_DCL handle get_type_handle(const std::type_info &tp, bool throw_if_missing) { detail::type_info *type_info = get_type_info(tp, throw_if_missing); return handle(type_info ? ((PyObject *) type_info->type) : nullptr); } // Searches the inheritance graph for a registered Python instance, using all_type_info(). -PYBIND11_NOINLINE handle find_registered_python_instance(void *src, +PYBIND11_NOINLINE_DCL handle find_registered_python_instance(void *src, const detail::type_info *tinfo) { auto it_instances = get_internals().registered_instances.equal_range(src); for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) { @@ -325,7 +325,7 @@ struct values_and_holders { * The returned object should be short-lived: in particular, it must not outlive the called-upon * instance. */ -PYBIND11_NOINLINE value_and_holder instance::get_value_and_holder(const type_info *find_type /*= nullptr default in common.h*/, bool throw_if_missing /*= true in common.h*/) { +PYBIND11_NOINLINE_DCL value_and_holder instance::get_value_and_holder(const type_info *find_type /*= nullptr default in common.h*/, bool throw_if_missing /*= true in common.h*/) { // Optimize common case: if (!find_type || Py_TYPE(this) == find_type->type) return value_and_holder(this, find_type, 0, 0); @@ -349,7 +349,7 @@ PYBIND11_NOINLINE value_and_holder instance::get_value_and_holder(const type_inf #endif } -PYBIND11_NOINLINE void instance::allocate_layout() { +PYBIND11_NOINLINE_DCL void instance::allocate_layout() { auto &tinfo = all_type_info(Py_TYPE(this)); const size_t n_types = tinfo.size(); @@ -397,19 +397,19 @@ PYBIND11_NOINLINE void instance::allocate_layout() { owned = true; } -PYBIND11_NOINLINE void instance::deallocate_layout() const { +PYBIND11_NOINLINE_DCL void instance::deallocate_layout() const { if (!simple_layout) PyMem_Free(nonsimple.values_and_holders); } -PYBIND11_NOINLINE bool isinstance_generic(handle obj, const std::type_info &tp) { +PYBIND11_NOINLINE_DCL bool isinstance_generic(handle obj, const std::type_info &tp) { handle type = detail::get_type_handle(tp, false); if (!type) return false; return isinstance(obj, type); } -PYBIND11_NOINLINE std::string error_string() { +PYBIND11_NOINLINE_DCL std::string error_string() { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_RuntimeError, "Unknown internal error occurred"); return "Unknown internal error occurred"; @@ -456,7 +456,7 @@ PYBIND11_NOINLINE std::string error_string() { return errorString; } -PYBIND11_NOINLINE handle get_object_handle(const void *ptr, const detail::type_info *type ) { +PYBIND11_NOINLINE_DCL handle get_object_handle(const void *ptr, const detail::type_info *type ) { auto &instances = get_internals().registered_instances; auto range = instances.equal_range(ptr); for (auto it = range.first; it != range.second; ++it) { @@ -483,12 +483,12 @@ inline PyThreadState *get_thread_state_unchecked() { } // Forward declarations -void keep_alive_impl(handle nurse, handle patient); +PYBIND11_NOINLINE_FWD void keep_alive_impl(handle nurse, handle patient); inline PyObject *make_new_instance(PyTypeObject *type); class type_caster_generic { public: - PYBIND11_NOINLINE type_caster_generic(const std::type_info &type_info) + PYBIND11_NOINLINE_DCL type_caster_generic(const std::type_info &type_info) : typeinfo(get_type_info(type_info)), cpptype(&type_info) { } type_caster_generic(const type_info *typeinfo) @@ -498,7 +498,7 @@ class type_caster_generic { return load_impl(src, convert); } - PYBIND11_NOINLINE static handle cast(const void *_src, return_value_policy policy, handle parent, + PYBIND11_NOINLINE_DCL static handle cast(const void *_src, return_value_policy policy, handle parent, const detail::type_info *tinfo, void *(*copy_constructor)(const void *), void *(*move_constructor)(const void *), @@ -622,7 +622,7 @@ class type_caster_generic { } void check_holder_compat() {} - PYBIND11_NOINLINE static void *local_load(PyObject *src, const type_info *ti) { + PYBIND11_NOINLINE_DCL static void *local_load(PyObject *src, const type_info *ti) { auto caster = type_caster_generic(ti); if (caster.load(src, false)) return caster.value; @@ -631,7 +631,7 @@ class type_caster_generic { /// Try to load with foreign typeinfo, if available. Used when there is no /// native typeinfo, or when the native one wasn't able to produce a value. - PYBIND11_NOINLINE bool try_load_foreign_module_local(handle src) { + PYBIND11_NOINLINE_DCL bool try_load_foreign_module_local(handle src) { constexpr auto *local_key = PYBIND11_MODULE_LOCAL_ID; const auto pytype = type::handle_of(src); if (!hasattr(pytype, local_key)) @@ -654,7 +654,7 @@ class type_caster_generic { // bits of code between here and copyable_holder_caster where the two classes need different // logic (without having to resort to virtual inheritance). template - PYBIND11_NOINLINE bool load_impl(handle src, bool convert) { + PYBIND11_NOINLINE_DCL bool load_impl(handle src, bool convert) { if (!src) return false; if (!typeinfo) return try_load_foreign_module_local(src); @@ -744,7 +744,7 @@ class type_caster_generic { // Called to do type lookup and wrap the pointer and type in a pair when a dynamic_cast // isn't needed or can't be used. If the type is unknown, sets the error and returns a pair // with .second = nullptr. (p.first = nullptr is not an error: it becomes None). - PYBIND11_NOINLINE static std::pair src_and_type( + PYBIND11_NOINLINE_DCL static std::pair src_and_type( const void *src, const std::type_info &cast_type, const std::type_info *rtti_type = nullptr) { if (auto *tpi = get_type_info(cast_type)) return {src, const_cast(tpi)}; diff --git a/include/pybind11/detail/typeid.h b/include/pybind11/detail/typeid.h index 39ba8ce0f7..2d5b8cefdf 100644 --- a/include/pybind11/detail/typeid.h +++ b/include/pybind11/detail/typeid.h @@ -29,7 +29,7 @@ inline void erase_all(std::string &string, const std::string &search) { } } -PYBIND11_NOINLINE void clean_type_id(std::string &name) { +PYBIND11_NOINLINE_DCL void clean_type_id(std::string &name) { #if defined(__GNUG__) int status = 0; std::unique_ptr res { diff --git a/include/pybind11/gil.h b/include/pybind11/gil.h index 32f1a8963b..25fa1c93c2 100644 --- a/include/pybind11/gil.h +++ b/include/pybind11/gil.h @@ -49,7 +49,7 @@ PYBIND11_NAMESPACE_END(detail) class gil_scoped_acquire { public: - PYBIND11_NOINLINE gil_scoped_acquire() { + PYBIND11_NOINLINE_DCL gil_scoped_acquire() { auto const &internals = detail::get_internals(); tstate = (PyThreadState *) PYBIND11_TLS_GET_VALUE(internals.tstate); @@ -85,7 +85,7 @@ class gil_scoped_acquire { ++tstate->gilstate_counter; } - PYBIND11_NOINLINE void dec_ref() { + PYBIND11_NOINLINE_DCL void dec_ref() { --tstate->gilstate_counter; #if !defined(NDEBUG) if (detail::get_thread_state_unchecked() != tstate) @@ -111,11 +111,11 @@ class gil_scoped_acquire { /// could be shutting down when this is called, as thread deletion is not /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and /// protect subsequent code. - PYBIND11_NOINLINE void disarm() { + PYBIND11_NOINLINE_DCL void disarm() { active = false; } - PYBIND11_NOINLINE ~gil_scoped_acquire() { + PYBIND11_NOINLINE_DCL ~gil_scoped_acquire() { dec_ref(); if (release) PyEval_SaveThread(); @@ -145,7 +145,7 @@ class gil_scoped_release { /// could be shutting down when this is called, as thread deletion is not /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and /// protect subsequent code. - PYBIND11_NOINLINE void disarm() { + PYBIND11_NOINLINE_DCL void disarm() { active = false; } diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index 2dc0f29f0b..31597f7330 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -104,7 +104,7 @@ struct numpy_internals { } }; -PYBIND11_NOINLINE void load_numpy_internals(numpy_internals* &ptr) { +PYBIND11_NOINLINE_DCL void load_numpy_internals(numpy_internals* &ptr) { ptr = &get_or_create_shared_data("_numpy_internals"); } @@ -1110,7 +1110,7 @@ struct field_descriptor { dtype descr; }; -PYBIND11_NOINLINE void register_structured_dtype( +PYBIND11_NOINLINE_DCL void register_structured_dtype( any_container fields, const std::type_info& tinfo, ssize_t itemsize, bool (*direct_converter)(PyObject *, void *&)) { diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index a337017ed8..4ac827fdcf 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -141,7 +141,7 @@ class cpp_function : public function { using unique_function_record = std::unique_ptr; /// Space optimization: don't inline this frequently instantiated fragment - PYBIND11_NOINLINE unique_function_record make_function_record() { + PYBIND11_NOINLINE_DCL unique_function_record make_function_record() { return unique_function_record(new detail::function_record()); } @@ -1051,7 +1051,7 @@ class module_ : public object { ``overwrite`` should almost always be false: attempting to overwrite objects that pybind11 has established will, in most cases, break things. \endrst */ - PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) { + PYBIND11_NOINLINE_DCL void add_object(const char *name, handle obj, bool overwrite = false) { if (!overwrite && hasattr(*this, name)) pybind11_fail("Error during initialization: multiple incompatible definitions with name \"" + std::string(name) + "\""); @@ -1666,7 +1666,7 @@ inline str enum_name(handle arg) { struct enum_base { enum_base(handle base, handle parent) : m_base(base), m_parent(parent) { } - PYBIND11_NOINLINE void init(bool is_arithmetic, bool is_convertible) { + PYBIND11_NOINLINE_DCL void init(bool is_arithmetic, bool is_convertible) { m_base.attr("__entries") = dict(); auto property = handle((PyObject *) &PyProperty_Type); auto static_property = handle((PyObject *) get_internals().static_property_type); @@ -1792,7 +1792,7 @@ struct enum_base { [](const object &arg) { return int_(arg); }, name("__hash__"), is_method(m_base)); } - PYBIND11_NOINLINE void value(char const* name_, object value, const char *doc = nullptr) { + PYBIND11_NOINLINE_DCL void value(char const* name_, object value, const char *doc = nullptr) { dict entries = m_base.attr("__entries"); str name(name_); if (entries.contains(name)) { @@ -1804,7 +1804,7 @@ struct enum_base { m_base.attr(name) = value; } - PYBIND11_NOINLINE void export_values() { + PYBIND11_NOINLINE_DCL void export_values() { dict entries = m_base.attr("__entries"); for (auto kv : entries) m_parent.attr(kv.first) = kv.second[int_(0)]; @@ -1869,7 +1869,7 @@ template class enum_ : public class_ { PYBIND11_NAMESPACE_BEGIN(detail) -PYBIND11_NOINLINE void keep_alive_impl(handle nurse, handle patient) { +PYBIND11_NOINLINE_DCL void keep_alive_impl(handle nurse, handle patient) { if (!nurse || !patient) pybind11_fail("Could not activate keep_alive!"); @@ -1896,7 +1896,7 @@ PYBIND11_NOINLINE void keep_alive_impl(handle nurse, handle patient) { } } -PYBIND11_NOINLINE void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret) { +PYBIND11_NOINLINE_DCL void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret) { auto get_arg = [&](size_t n) { if (n == 0) return ret; @@ -2146,7 +2146,7 @@ exception ®ister_local_exception(handle scope, } PYBIND11_NAMESPACE_BEGIN(detail) -PYBIND11_NOINLINE void print(const tuple &args, const dict &kwargs) { +PYBIND11_NOINLINE_DCL void print(const tuple &args, const dict &kwargs) { auto strings = tuple(args.size()); for (size_t i = 0; i < args.size(); ++i) { strings[i] = str(args[i]); diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 21e14960cf..f07f52f815 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -24,7 +24,7 @@ struct arg; struct arg_v; PYBIND11_NAMESPACE_BEGIN(detail) class args_proxy; -bool isinstance_generic(handle obj, const std::type_info &tp); +PYBIND11_NOINLINE_FWD bool isinstance_generic(handle obj, const std::type_info &tp); // Accessor forward declarations template class accessor; @@ -316,7 +316,7 @@ template T reinterpret_borrow(handle h) { return {h, object::borrow template T reinterpret_steal(handle h) { return {h, object::stolen_t{}}; } PYBIND11_NAMESPACE_BEGIN(detail) -std::string error_string(); +PYBIND11_NOINLINE_FWD std::string error_string(); PYBIND11_NAMESPACE_END(detail) #if defined(_MSC_VER) From 43c6f22ca6934e346358b2d4a353e833ba09247a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 2 Aug 2021 14:27:49 -0700 Subject: [PATCH 03/18] Updating PYBIND11_NOINLINE_DCL in Doxyfile. --- docs/Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index c8562952ef..22af784890 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -20,4 +20,4 @@ WARNINGS = YES WARN_IF_UNDOCUMENTED = NO PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS \ PY_MAJOR_VERSION=3 \ - PYBIND11_NOINLINE + PYBIND11_NOINLINE_DCL From d564545eb351696d59a8af422e831ee3de6faecf Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 2 Aug 2021 15:09:21 -0700 Subject: [PATCH 04/18] Trying noinline, noinline for {CUDA, GCC7, GCC8} --- include/pybind11/detail/common.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 5fdb3cdc8c..f4e3a7c43e 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -100,8 +100,8 @@ #endif #if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) -# define PYBIND11_NOINLINE_DCL inline -# define PYBIND11_NOINLINE_FWD inline +# define PYBIND11_NOINLINE_DCL __attribute__ ((noinline)) inline +# define PYBIND11_NOINLINE_FWD __attribute__ ((noinline)) inline #elif defined(_MSC_VER) # define PYBIND11_NOINLINE_DCL __declspec(noinline) inline # define PYBIND11_NOINLINE_FWD From 4984ab5bfe8c7986b3360302e24d6d4dd88733e3 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 2 Aug 2021 15:15:09 -0700 Subject: [PATCH 05/18] Trying noinline, inline for {CUDA, GCC7, GCC8} --- include/pybind11/detail/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index f4e3a7c43e..fdb174f344 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -101,7 +101,7 @@ #if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) # define PYBIND11_NOINLINE_DCL __attribute__ ((noinline)) inline -# define PYBIND11_NOINLINE_FWD __attribute__ ((noinline)) inline +# define PYBIND11_NOINLINE_FWD inline #elif defined(_MSC_VER) # define PYBIND11_NOINLINE_DCL __declspec(noinline) inline # define PYBIND11_NOINLINE_FWD From aef2edbbbc1dd13ba06114e03d37597cdf7e4289 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 2 Aug 2021 15:46:01 -0700 Subject: [PATCH 06/18] Adding GCC -Wattributes `pragma` in 3 header files. --- include/pybind11/attr.h | 12 ++++++++++++ include/pybind11/detail/common.h | 4 ++-- include/pybind11/detail/type_caster_base.h | 14 +++++++++++++- include/pybind11/pytypes.h | 18 ++++++++++++++---- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 36a4343400..42f67c8d1f 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -124,8 +124,20 @@ enum op_id : int; enum op_type : int; struct undefined_t; template struct op_; + +#if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) +# define PYBIND11_PRAGMA_NOINLINE_FWD +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif + PYBIND11_NOINLINE_FWD void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); +#if defined(PYBIND11_PRAGMA_NOINLINE_FWD) +# pragma GCC diagnostic pop +# undef PYBIND11_PRAGMA_NOINLINE_FWD +#endif + /// Internal data structure which holds metadata about a keyword argument struct argument_record { const char *name; ///< Argument name diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index fdb174f344..401d03cb4e 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -99,8 +99,8 @@ # endif #endif -#if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) -# define PYBIND11_NOINLINE_DCL __attribute__ ((noinline)) inline +#if defined(PYBIND11_NOINLINE_DISABLED) +# define PYBIND11_NOINLINE_DCL inline # define PYBIND11_NOINLINE_FWD inline #elif defined(_MSC_VER) # define PYBIND11_NOINLINE_DCL __declspec(noinline) inline diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index eae5a12f4a..cce7a90df3 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -483,9 +483,21 @@ inline PyThreadState *get_thread_state_unchecked() { } // Forward declarations -PYBIND11_NOINLINE_FWD void keep_alive_impl(handle nurse, handle patient); inline PyObject *make_new_instance(PyTypeObject *type); +#if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) +# define PYBIND11_PRAGMA_NOINLINE_FWD +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif + +PYBIND11_NOINLINE_FWD void keep_alive_impl(handle nurse, handle patient); + +#if defined(PYBIND11_PRAGMA_NOINLINE_FWD) +# pragma GCC diagnostic pop +# undef PYBIND11_PRAGMA_NOINLINE_FWD +#endif + class type_caster_generic { public: PYBIND11_NOINLINE_DCL type_caster_generic(const std::type_info &type_info) diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index f07f52f815..54e9ed28a5 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -23,8 +23,22 @@ class type; struct arg; struct arg_v; PYBIND11_NAMESPACE_BEGIN(detail) + class args_proxy; + +#if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) +# define PYBIND11_PRAGMA_NOINLINE_FWD +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif + PYBIND11_NOINLINE_FWD bool isinstance_generic(handle obj, const std::type_info &tp); +PYBIND11_NOINLINE_FWD std::string error_string(); + +#if defined(PYBIND11_PRAGMA_NOINLINE_FWD) +# pragma GCC diagnostic pop +# undef PYBIND11_PRAGMA_NOINLINE_FWD +#endif // Accessor forward declarations template class accessor; @@ -315,10 +329,6 @@ template T reinterpret_borrow(handle h) { return {h, object::borrow \endrst */ template T reinterpret_steal(handle h) { return {h, object::stolen_t{}}; } -PYBIND11_NAMESPACE_BEGIN(detail) -PYBIND11_NOINLINE_FWD std::string error_string(); -PYBIND11_NAMESPACE_END(detail) - #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable: 4275 4251) // warning C4275: An exported class was derived from a class that wasn't exported. Can be ignored when derived from a STL class. From 7181a118cb5f23854c8f19e7d07791990840f57a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 2 Aug 2021 16:37:09 -0700 Subject: [PATCH 07/18] Introducing PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED, used in 9 header files. --- include/pybind11/attr.h | 21 +++++++++----------- include/pybind11/detail/common.h | 16 +++++++++++++++ include/pybind11/detail/internals.h | 9 +++++++++ include/pybind11/detail/type_caster_base.h | 23 ++++++++++------------ include/pybind11/detail/typeid.h | 9 +++++++++ include/pybind11/gil.h | 10 +++++++++- include/pybind11/numpy.h | 9 +++++++++ include/pybind11/pybind11.h | 9 +++++++++ include/pybind11/pytypes.h | 21 +++++++++----------- 9 files changed, 89 insertions(+), 38 deletions(-) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 42f67c8d1f..2a88ee1dc6 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -12,6 +12,11 @@ #include "cast.h" +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif + PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) /// \addtogroup annotations @@ -124,20 +129,8 @@ enum op_id : int; enum op_type : int; struct undefined_t; template struct op_; - -#if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) -# define PYBIND11_PRAGMA_NOINLINE_FWD -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wattributes" -#endif - PYBIND11_NOINLINE_FWD void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); -#if defined(PYBIND11_PRAGMA_NOINLINE_FWD) -# pragma GCC diagnostic pop -# undef PYBIND11_PRAGMA_NOINLINE_FWD -#endif - /// Internal data structure which holds metadata about a keyword argument struct argument_record { const char *name; ///< Argument name @@ -574,3 +567,7 @@ constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) { PYBIND11_NAMESPACE_END(detail) PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic pop +#endif diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 401d03cb4e..5c0c785e00 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -110,6 +110,13 @@ # define PYBIND11_NOINLINE_FWD #endif +#if !defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) && \ + !defined(PYBIND11_NOINLINE_DISABLED) && \ + (defined(__CUDACC__) || \ + (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8))) +# define PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED +#endif + #if defined(__MINGW32__) // For unknown reasons all PYBIND11_DEPRECATED member trigger a warning when declared // whether it is used or not @@ -379,6 +386,11 @@ extern "C" { } \ void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ & (variable)) +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif + PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) using ssize_t = Py_ssize_t; @@ -965,3 +977,7 @@ constexpr inline bool silence_msvc_c4127(bool cond) { return cond; } PYBIND11_NAMESPACE_END(detail) PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic pop +#endif diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index eac3079c68..83ced63a3b 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -11,6 +11,11 @@ #include "../pytypes.h" +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif + PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) using ExceptionTranslator = void (*)(std::exception_ptr); @@ -380,3 +385,7 @@ T &get_or_create_shared_data(const std::string &name) { } PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic pop +#endif diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index cce7a90df3..f2f72106bf 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -25,6 +25,11 @@ #include #include +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif + PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(detail) @@ -483,20 +488,8 @@ inline PyThreadState *get_thread_state_unchecked() { } // Forward declarations -inline PyObject *make_new_instance(PyTypeObject *type); - -#if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) -# define PYBIND11_PRAGMA_NOINLINE_FWD -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wattributes" -#endif - PYBIND11_NOINLINE_FWD void keep_alive_impl(handle nurse, handle patient); - -#if defined(PYBIND11_PRAGMA_NOINLINE_FWD) -# pragma GCC diagnostic pop -# undef PYBIND11_PRAGMA_NOINLINE_FWD -#endif +inline PyObject *make_new_instance(PyTypeObject *type); class type_caster_generic { public: @@ -961,3 +954,7 @@ template class type_caster_base : public type_caster_generic { PYBIND11_NAMESPACE_END(detail) PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic pop +#endif diff --git a/include/pybind11/detail/typeid.h b/include/pybind11/detail/typeid.h index 2d5b8cefdf..bb24d9b615 100644 --- a/include/pybind11/detail/typeid.h +++ b/include/pybind11/detail/typeid.h @@ -18,6 +18,11 @@ #include "common.h" +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif + PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(detail) /// Erase all occurrences of a substring @@ -53,3 +58,7 @@ template static std::string type_id() { } PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic pop +#endif diff --git a/include/pybind11/gil.h b/include/pybind11/gil.h index 25fa1c93c2..ac0bcdf3bc 100644 --- a/include/pybind11/gil.h +++ b/include/pybind11/gil.h @@ -12,8 +12,12 @@ #include "detail/common.h" #include "detail/internals.h" -PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif +PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(detail) @@ -191,3 +195,7 @@ class gil_scoped_release { #endif PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic pop +#endif diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index 31597f7330..f295dfa51a 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -30,6 +30,11 @@ # pragma warning(disable: 4127) // warning C4127: Conditional expression is constant #endif +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif + /* This will be true on all flat address space platforms and allows us to reduce the whole npy_intp / ssize_t / Py_intptr_t business down to just ssize_t for all size and dimension types (e.g. shape, strides, indexing), instead of inflicting this @@ -1709,6 +1714,10 @@ Helper vectorize(Return (Class::*f)(Args...) const) { PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic pop +#endif + #if defined(_MSC_VER) #pragma warning(pop) #endif diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 4ac827fdcf..9d9140aec0 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -47,6 +47,11 @@ # pragma GCC diagnostic ignored "-Wnoexcept-type" #endif +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif + PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(detail) @@ -2374,6 +2379,10 @@ inline function get_overload(const T *this_ptr, const char *name) { PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic pop +#endif + #if defined(__GNUC__) && __GNUC__ == 7 # pragma GCC diagnostic pop // -Wnoexcept-type #endif diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 54e9ed28a5..477a5cd221 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -14,6 +14,11 @@ #include #include +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wattributes" +#endif + PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) /* A few forward declarations */ @@ -25,21 +30,9 @@ struct arg; struct arg_v; PYBIND11_NAMESPACE_BEGIN(detail) class args_proxy; - -#if defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)) -# define PYBIND11_PRAGMA_NOINLINE_FWD -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wattributes" -#endif - PYBIND11_NOINLINE_FWD bool isinstance_generic(handle obj, const std::type_info &tp); PYBIND11_NOINLINE_FWD std::string error_string(); -#if defined(PYBIND11_PRAGMA_NOINLINE_FWD) -# pragma GCC diagnostic pop -# undef PYBIND11_PRAGMA_NOINLINE_FWD -#endif - // Accessor forward declarations template class accessor; namespace accessor_policies { @@ -1773,3 +1766,7 @@ PYBIND11_MATH_OPERATOR_BINARY(operator>>=, PyNumber_InPlaceRshift) PYBIND11_NAMESPACE_END(detail) PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# pragma GCC diagnostic pop +#endif From a893084f242da26d6a5439d60186da26e1c39259 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 2 Aug 2021 18:12:07 -0700 Subject: [PATCH 08/18] Removing ICC pragma 2196, to see if it is still needed. --- include/pybind11/detail/common.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 5c0c785e00..a227b615fd 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -56,9 +56,6 @@ # elif __INTEL_COMPILER < 1900 && defined(PYBIND11_CPP14) # error pybind11 supports only C++11 with Intel C++ compiler v18. Use v19 or newer for C++14. # endif -/* The following pragma cannot be pop'ed: - https://community.intel.com/t5/Intel-C-Compiler/Inline-and-no-inline-warning/td-p/1216764 */ -# pragma warning disable 2196 // warning #2196: routine is both "inline" and "noinline" #elif defined(__clang__) && !defined(__apple_build_version__) # if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3) # error pybind11 requires clang 3.3 or newer From 71a2799ccf7d2a5cfeebddee39376b76b0f57ed8 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 2 Aug 2021 18:20:06 -0700 Subject: [PATCH 09/18] Trying noinline, noinline for ICC --- include/pybind11/detail/common.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index a227b615fd..7a73c23b0c 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -99,6 +99,9 @@ #if defined(PYBIND11_NOINLINE_DISABLED) # define PYBIND11_NOINLINE_DCL inline # define PYBIND11_NOINLINE_FWD inline +#elif defined(__INTEL_COMPILER) +# define PYBIND11_NOINLINE_DCL __attribute__ ((noinline)) inline +# define PYBIND11_NOINLINE_FWD __attribute__ ((noinline)) inline #elif defined(_MSC_VER) # define PYBIND11_NOINLINE_DCL __declspec(noinline) inline # define PYBIND11_NOINLINE_FWD From 2307390bf0650283081f9a2a1472b7b138a21bef Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 2 Aug 2021 18:24:21 -0700 Subject: [PATCH 10/18] Trying noinline, inline for ICC --- include/pybind11/detail/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 7a73c23b0c..253f3be0c8 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -101,7 +101,7 @@ # define PYBIND11_NOINLINE_FWD inline #elif defined(__INTEL_COMPILER) # define PYBIND11_NOINLINE_DCL __attribute__ ((noinline)) inline -# define PYBIND11_NOINLINE_FWD __attribute__ ((noinline)) inline +# define PYBIND11_NOINLINE_FWD inline #elif defined(_MSC_VER) # define PYBIND11_NOINLINE_DCL __declspec(noinline) inline # define PYBIND11_NOINLINE_FWD From 236edb2beeff16012cc88da4e7ccf81944035f78 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 3 Aug 2021 12:51:51 -0700 Subject: [PATCH 11/18] Restoring ICC pragma 2196, introducing PYBIND11_NOINLINE_FORCED, defined for testing. --- include/pybind11/detail/common.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 253f3be0c8..56027b95fe 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -56,6 +56,9 @@ # elif __INTEL_COMPILER < 1900 && defined(PYBIND11_CPP14) # error pybind11 supports only C++11 with Intel C++ compiler v18. Use v19 or newer for C++14. # endif +/* The following pragma cannot be pop'ed: + https://community.intel.com/t5/Intel-C-Compiler/Inline-and-no-inline-warning/td-p/1216764 */ +# pragma warning disable 2196 // warning #2196: routine is both "inline" and "noinline" #elif defined(__clang__) && !defined(__apple_build_version__) # if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3) # error pybind11 requires clang 3.3 or newer @@ -96,6 +99,17 @@ # endif #endif +// For CUDA, GCC7, GCC8 (and maybe some other platforms): +// PYBIND11_NOINLINE_FORCED is incompatible with `-Wattributes -Werror`. +// When defining PYBIND11_NOINLINE_FORCED, it is best to also use +// `-Wno-attributes` (or not to use `-Werror` and ignore the warnings). +#define PYBIND11_NOINLINE_FORCED +#if !defined(PYBIND11_NOINLINE_FORCED) && \ + (defined(__CUDACC__) || \ + (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8))) +# define PYBIND11_NOINLINE_DISABLED +#endif + #if defined(PYBIND11_NOINLINE_DISABLED) # define PYBIND11_NOINLINE_DCL inline # define PYBIND11_NOINLINE_FWD inline @@ -110,6 +124,11 @@ # define PYBIND11_NOINLINE_FWD #endif +// DECISION TO BE MADE before this PR is merged: +// ---------------------------------------------------------------------------- +// This code and the 9 x 2 pragma blocks referring to +// PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED could be purged. +// ---------------------------------------------------------------------------- #if !defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) && \ !defined(PYBIND11_NOINLINE_DISABLED) && \ (defined(__CUDACC__) || \ From c22bd6567576d750d2ac6abcfd4f9310002c833d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 3 Aug 2021 13:26:08 -0700 Subject: [PATCH 12/18] Removing code accidentally left in (was for experimentation only). --- include/pybind11/detail/common.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 56027b95fe..cb3733688c 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -113,9 +113,6 @@ #if defined(PYBIND11_NOINLINE_DISABLED) # define PYBIND11_NOINLINE_DCL inline # define PYBIND11_NOINLINE_FWD inline -#elif defined(__INTEL_COMPILER) -# define PYBIND11_NOINLINE_DCL __attribute__ ((noinline)) inline -# define PYBIND11_NOINLINE_FWD inline #elif defined(_MSC_VER) # define PYBIND11_NOINLINE_DCL __declspec(noinline) inline # define PYBIND11_NOINLINE_FWD From 3c6098503000fc996fe602e7838cd43cba71a715 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 3 Aug 2021 13:30:08 -0700 Subject: [PATCH 13/18] Removing one-time-test define. --- include/pybind11/detail/common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index cb3733688c..13e56cc51a 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -103,7 +103,6 @@ // PYBIND11_NOINLINE_FORCED is incompatible with `-Wattributes -Werror`. // When defining PYBIND11_NOINLINE_FORCED, it is best to also use // `-Wno-attributes` (or not to use `-Werror` and ignore the warnings). -#define PYBIND11_NOINLINE_FORCED #if !defined(PYBIND11_NOINLINE_FORCED) && \ (defined(__CUDACC__) || \ (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8))) From 3b2e642d6bed5def182a4a1c646fbfd6c2ff0bc8 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 3 Aug 2021 14:33:48 -0700 Subject: [PATCH 14/18] Removing PYBIND11_NOINLINE_FWD macro (after learning that it makes no sense). --- docs/Doxyfile | 2 +- include/pybind11/attr.h | 6 ++-- include/pybind11/detail/common.h | 15 ++++----- include/pybind11/detail/internals.h | 6 ++-- include/pybind11/detail/type_caster_base.h | 38 +++++++++++----------- include/pybind11/detail/typeid.h | 2 +- include/pybind11/gil.h | 10 +++--- include/pybind11/numpy.h | 4 +-- include/pybind11/pybind11.h | 16 ++++----- include/pybind11/pytypes.h | 4 +-- 10 files changed, 51 insertions(+), 52 deletions(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index 22af784890..c8562952ef 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -20,4 +20,4 @@ WARNINGS = YES WARN_IF_UNDOCUMENTED = NO PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS \ PY_MAJOR_VERSION=3 \ - PYBIND11_NOINLINE_DCL + PYBIND11_NOINLINE diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 2a88ee1dc6..5efd7b4f87 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -129,7 +129,7 @@ enum op_id : int; enum op_type : int; struct undefined_t; template struct op_; -PYBIND11_NOINLINE_FWD void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); +void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); /// Internal data structure which holds metadata about a keyword argument struct argument_record { @@ -225,7 +225,7 @@ struct function_record { /// Special data structure which (temporarily) holds metadata about a bound class struct type_record { - PYBIND11_NOINLINE_DCL type_record() + PYBIND11_NOINLINE type_record() : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), default_holder(true), module_local(false), is_final(false) { } @@ -283,7 +283,7 @@ struct type_record { /// Is the class inheritable from python classes? bool is_final : 1; - PYBIND11_NOINLINE_DCL void add_base(const std::type_info &base, void *(*caster)(void *)) { + PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) { auto base_info = detail::get_type_info(base, false); if (!base_info) { std::string tname(base.name()); diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 13e56cc51a..68af33fb53 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -109,15 +109,14 @@ # define PYBIND11_NOINLINE_DISABLED #endif +// Note: Forward declaration should never be `inline`: +// https://stackoverflow.com/questions/9317473/forward-declaration-of-inline-functions #if defined(PYBIND11_NOINLINE_DISABLED) -# define PYBIND11_NOINLINE_DCL inline -# define PYBIND11_NOINLINE_FWD inline +# define PYBIND11_NOINLINE inline #elif defined(_MSC_VER) -# define PYBIND11_NOINLINE_DCL __declspec(noinline) inline -# define PYBIND11_NOINLINE_FWD +# define PYBIND11_NOINLINE __declspec(noinline) inline #else -# define PYBIND11_NOINLINE_DCL __attribute__ ((noinline)) inline -# define PYBIND11_NOINLINE_FWD +# define PYBIND11_NOINLINE __attribute__ ((noinline)) inline #endif // DECISION TO BE MADE before this PR is merged: @@ -810,8 +809,8 @@ PYBIND11_RUNTIME_EXCEPTION(import_error, PyExc_ImportError) PYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or handle::call fail due to a type casting error PYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally -[[noreturn]] PYBIND11_NOINLINE_DCL void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } -[[noreturn]] PYBIND11_NOINLINE_DCL void pybind11_fail(const std::string &reason) { throw std::runtime_error(reason); } +[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } +[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const std::string &reason) { throw std::runtime_error(reason); } template struct format_descriptor { }; diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 83ced63a3b..c5f341cb03 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -262,7 +262,7 @@ inline void translate_local_exception(std::exception_ptr p) { #endif /// Return a reference to the current `internals` data -PYBIND11_NOINLINE_DCL internals &get_internals() { +PYBIND11_NOINLINE internals &get_internals() { auto **&internals_pp = get_internals_pp(); if (internals_pp && *internals_pp) return **internals_pp; @@ -357,14 +357,14 @@ PYBIND11_NAMESPACE_END(detail) /// Returns a named pointer that is shared among all extension modules (using the same /// pybind11 version) running in the current interpreter. Names starting with underscores /// are reserved for internal usage. Returns `nullptr` if no matching entry was found. -PYBIND11_NOINLINE_DCL void *get_shared_data(const std::string &name) { +PYBIND11_NOINLINE void *get_shared_data(const std::string &name) { auto &internals = detail::get_internals(); auto it = internals.shared_data.find(name); return it != internals.shared_data.end() ? it->second : nullptr; } /// Set the shared data that can be later recovered by `get_shared_data()`. -PYBIND11_NOINLINE_DCL void *set_shared_data(const std::string &name, void *data) { +PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) { detail::get_internals().shared_data[name] = data; return data; } diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index f2f72106bf..eb28233612 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -59,7 +59,7 @@ class loader_life_support { /// This can only be used inside a pybind11-bound function, either by `argument_loader` /// at argument preparation time or by `py::cast()` at execution time. - PYBIND11_NOINLINE_DCL static void add_patient(handle h) { + PYBIND11_NOINLINE static void add_patient(handle h) { auto &stack = get_internals().loader_patient_stack; if (stack.empty()) throw cast_error("When called outside a bound function, py::cast() cannot " @@ -86,7 +86,7 @@ class loader_life_support { inline std::pair all_type_info_get_cache(PyTypeObject *type); // Populates a just-created cache entry. -PYBIND11_NOINLINE_DCL void all_type_info_populate(PyTypeObject *t, std::vector &bases) { +PYBIND11_NOINLINE void all_type_info_populate(PyTypeObject *t, std::vector &bases) { std::vector check; for (handle parent : reinterpret_borrow(t->tp_bases)) check.push_back((PyTypeObject *) parent.ptr()); @@ -155,7 +155,7 @@ inline const std::vector &all_type_info(PyTypeObject *type) * ancestors are pybind11-registered. Throws an exception if there are multiple bases--use * `all_type_info` instead if you want to support multiple bases. */ -PYBIND11_NOINLINE_DCL detail::type_info* get_type_info(PyTypeObject *type) { +PYBIND11_NOINLINE detail::type_info* get_type_info(PyTypeObject *type) { auto &bases = all_type_info(type); if (bases.empty()) return nullptr; @@ -181,7 +181,7 @@ inline detail::type_info *get_global_type_info(const std::type_index &tp) { } /// Return the type info for a given C++ type; on lookup failure can either throw or return nullptr. -PYBIND11_NOINLINE_DCL detail::type_info *get_type_info(const std::type_index &tp, +PYBIND11_NOINLINE detail::type_info *get_type_info(const std::type_index &tp, bool throw_if_missing = false) { if (auto ltype = get_local_type_info(tp)) return ltype; @@ -196,13 +196,13 @@ PYBIND11_NOINLINE_DCL detail::type_info *get_type_info(const std::type_index &tp return nullptr; } -PYBIND11_NOINLINE_DCL handle get_type_handle(const std::type_info &tp, bool throw_if_missing) { +PYBIND11_NOINLINE handle get_type_handle(const std::type_info &tp, bool throw_if_missing) { detail::type_info *type_info = get_type_info(tp, throw_if_missing); return handle(type_info ? ((PyObject *) type_info->type) : nullptr); } // Searches the inheritance graph for a registered Python instance, using all_type_info(). -PYBIND11_NOINLINE_DCL handle find_registered_python_instance(void *src, +PYBIND11_NOINLINE handle find_registered_python_instance(void *src, const detail::type_info *tinfo) { auto it_instances = get_internals().registered_instances.equal_range(src); for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) { @@ -330,7 +330,7 @@ struct values_and_holders { * The returned object should be short-lived: in particular, it must not outlive the called-upon * instance. */ -PYBIND11_NOINLINE_DCL value_and_holder instance::get_value_and_holder(const type_info *find_type /*= nullptr default in common.h*/, bool throw_if_missing /*= true in common.h*/) { +PYBIND11_NOINLINE value_and_holder instance::get_value_and_holder(const type_info *find_type /*= nullptr default in common.h*/, bool throw_if_missing /*= true in common.h*/) { // Optimize common case: if (!find_type || Py_TYPE(this) == find_type->type) return value_and_holder(this, find_type, 0, 0); @@ -354,7 +354,7 @@ PYBIND11_NOINLINE_DCL value_and_holder instance::get_value_and_holder(const type #endif } -PYBIND11_NOINLINE_DCL void instance::allocate_layout() { +PYBIND11_NOINLINE void instance::allocate_layout() { auto &tinfo = all_type_info(Py_TYPE(this)); const size_t n_types = tinfo.size(); @@ -402,19 +402,19 @@ PYBIND11_NOINLINE_DCL void instance::allocate_layout() { owned = true; } -PYBIND11_NOINLINE_DCL void instance::deallocate_layout() const { +PYBIND11_NOINLINE void instance::deallocate_layout() const { if (!simple_layout) PyMem_Free(nonsimple.values_and_holders); } -PYBIND11_NOINLINE_DCL bool isinstance_generic(handle obj, const std::type_info &tp) { +PYBIND11_NOINLINE bool isinstance_generic(handle obj, const std::type_info &tp) { handle type = detail::get_type_handle(tp, false); if (!type) return false; return isinstance(obj, type); } -PYBIND11_NOINLINE_DCL std::string error_string() { +PYBIND11_NOINLINE std::string error_string() { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_RuntimeError, "Unknown internal error occurred"); return "Unknown internal error occurred"; @@ -461,7 +461,7 @@ PYBIND11_NOINLINE_DCL std::string error_string() { return errorString; } -PYBIND11_NOINLINE_DCL handle get_object_handle(const void *ptr, const detail::type_info *type ) { +PYBIND11_NOINLINE handle get_object_handle(const void *ptr, const detail::type_info *type ) { auto &instances = get_internals().registered_instances; auto range = instances.equal_range(ptr); for (auto it = range.first; it != range.second; ++it) { @@ -488,12 +488,12 @@ inline PyThreadState *get_thread_state_unchecked() { } // Forward declarations -PYBIND11_NOINLINE_FWD void keep_alive_impl(handle nurse, handle patient); +void keep_alive_impl(handle nurse, handle patient); inline PyObject *make_new_instance(PyTypeObject *type); class type_caster_generic { public: - PYBIND11_NOINLINE_DCL type_caster_generic(const std::type_info &type_info) + PYBIND11_NOINLINE type_caster_generic(const std::type_info &type_info) : typeinfo(get_type_info(type_info)), cpptype(&type_info) { } type_caster_generic(const type_info *typeinfo) @@ -503,7 +503,7 @@ class type_caster_generic { return load_impl(src, convert); } - PYBIND11_NOINLINE_DCL static handle cast(const void *_src, return_value_policy policy, handle parent, + PYBIND11_NOINLINE static handle cast(const void *_src, return_value_policy policy, handle parent, const detail::type_info *tinfo, void *(*copy_constructor)(const void *), void *(*move_constructor)(const void *), @@ -627,7 +627,7 @@ class type_caster_generic { } void check_holder_compat() {} - PYBIND11_NOINLINE_DCL static void *local_load(PyObject *src, const type_info *ti) { + PYBIND11_NOINLINE static void *local_load(PyObject *src, const type_info *ti) { auto caster = type_caster_generic(ti); if (caster.load(src, false)) return caster.value; @@ -636,7 +636,7 @@ class type_caster_generic { /// Try to load with foreign typeinfo, if available. Used when there is no /// native typeinfo, or when the native one wasn't able to produce a value. - PYBIND11_NOINLINE_DCL bool try_load_foreign_module_local(handle src) { + PYBIND11_NOINLINE bool try_load_foreign_module_local(handle src) { constexpr auto *local_key = PYBIND11_MODULE_LOCAL_ID; const auto pytype = type::handle_of(src); if (!hasattr(pytype, local_key)) @@ -659,7 +659,7 @@ class type_caster_generic { // bits of code between here and copyable_holder_caster where the two classes need different // logic (without having to resort to virtual inheritance). template - PYBIND11_NOINLINE_DCL bool load_impl(handle src, bool convert) { + PYBIND11_NOINLINE bool load_impl(handle src, bool convert) { if (!src) return false; if (!typeinfo) return try_load_foreign_module_local(src); @@ -749,7 +749,7 @@ class type_caster_generic { // Called to do type lookup and wrap the pointer and type in a pair when a dynamic_cast // isn't needed or can't be used. If the type is unknown, sets the error and returns a pair // with .second = nullptr. (p.first = nullptr is not an error: it becomes None). - PYBIND11_NOINLINE_DCL static std::pair src_and_type( + PYBIND11_NOINLINE static std::pair src_and_type( const void *src, const std::type_info &cast_type, const std::type_info *rtti_type = nullptr) { if (auto *tpi = get_type_info(cast_type)) return {src, const_cast(tpi)}; diff --git a/include/pybind11/detail/typeid.h b/include/pybind11/detail/typeid.h index bb24d9b615..cb07ba7fbc 100644 --- a/include/pybind11/detail/typeid.h +++ b/include/pybind11/detail/typeid.h @@ -34,7 +34,7 @@ inline void erase_all(std::string &string, const std::string &search) { } } -PYBIND11_NOINLINE_DCL void clean_type_id(std::string &name) { +PYBIND11_NOINLINE void clean_type_id(std::string &name) { #if defined(__GNUG__) int status = 0; std::unique_ptr res { diff --git a/include/pybind11/gil.h b/include/pybind11/gil.h index ac0bcdf3bc..5bcfafcf37 100644 --- a/include/pybind11/gil.h +++ b/include/pybind11/gil.h @@ -53,7 +53,7 @@ PYBIND11_NAMESPACE_END(detail) class gil_scoped_acquire { public: - PYBIND11_NOINLINE_DCL gil_scoped_acquire() { + PYBIND11_NOINLINE gil_scoped_acquire() { auto const &internals = detail::get_internals(); tstate = (PyThreadState *) PYBIND11_TLS_GET_VALUE(internals.tstate); @@ -89,7 +89,7 @@ class gil_scoped_acquire { ++tstate->gilstate_counter; } - PYBIND11_NOINLINE_DCL void dec_ref() { + PYBIND11_NOINLINE void dec_ref() { --tstate->gilstate_counter; #if !defined(NDEBUG) if (detail::get_thread_state_unchecked() != tstate) @@ -115,11 +115,11 @@ class gil_scoped_acquire { /// could be shutting down when this is called, as thread deletion is not /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and /// protect subsequent code. - PYBIND11_NOINLINE_DCL void disarm() { + PYBIND11_NOINLINE void disarm() { active = false; } - PYBIND11_NOINLINE_DCL ~gil_scoped_acquire() { + PYBIND11_NOINLINE ~gil_scoped_acquire() { dec_ref(); if (release) PyEval_SaveThread(); @@ -149,7 +149,7 @@ class gil_scoped_release { /// could be shutting down when this is called, as thread deletion is not /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and /// protect subsequent code. - PYBIND11_NOINLINE_DCL void disarm() { + PYBIND11_NOINLINE void disarm() { active = false; } diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index f295dfa51a..941c268b5c 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -109,7 +109,7 @@ struct numpy_internals { } }; -PYBIND11_NOINLINE_DCL void load_numpy_internals(numpy_internals* &ptr) { +PYBIND11_NOINLINE void load_numpy_internals(numpy_internals* &ptr) { ptr = &get_or_create_shared_data("_numpy_internals"); } @@ -1115,7 +1115,7 @@ struct field_descriptor { dtype descr; }; -PYBIND11_NOINLINE_DCL void register_structured_dtype( +PYBIND11_NOINLINE void register_structured_dtype( any_container fields, const std::type_info& tinfo, ssize_t itemsize, bool (*direct_converter)(PyObject *, void *&)) { diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 9d9140aec0..ab8ac22532 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -146,7 +146,7 @@ class cpp_function : public function { using unique_function_record = std::unique_ptr; /// Space optimization: don't inline this frequently instantiated fragment - PYBIND11_NOINLINE_DCL unique_function_record make_function_record() { + PYBIND11_NOINLINE unique_function_record make_function_record() { return unique_function_record(new detail::function_record()); } @@ -1056,7 +1056,7 @@ class module_ : public object { ``overwrite`` should almost always be false: attempting to overwrite objects that pybind11 has established will, in most cases, break things. \endrst */ - PYBIND11_NOINLINE_DCL void add_object(const char *name, handle obj, bool overwrite = false) { + PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) { if (!overwrite && hasattr(*this, name)) pybind11_fail("Error during initialization: multiple incompatible definitions with name \"" + std::string(name) + "\""); @@ -1671,7 +1671,7 @@ inline str enum_name(handle arg) { struct enum_base { enum_base(handle base, handle parent) : m_base(base), m_parent(parent) { } - PYBIND11_NOINLINE_DCL void init(bool is_arithmetic, bool is_convertible) { + PYBIND11_NOINLINE void init(bool is_arithmetic, bool is_convertible) { m_base.attr("__entries") = dict(); auto property = handle((PyObject *) &PyProperty_Type); auto static_property = handle((PyObject *) get_internals().static_property_type); @@ -1797,7 +1797,7 @@ struct enum_base { [](const object &arg) { return int_(arg); }, name("__hash__"), is_method(m_base)); } - PYBIND11_NOINLINE_DCL void value(char const* name_, object value, const char *doc = nullptr) { + PYBIND11_NOINLINE void value(char const* name_, object value, const char *doc = nullptr) { dict entries = m_base.attr("__entries"); str name(name_); if (entries.contains(name)) { @@ -1809,7 +1809,7 @@ struct enum_base { m_base.attr(name) = value; } - PYBIND11_NOINLINE_DCL void export_values() { + PYBIND11_NOINLINE void export_values() { dict entries = m_base.attr("__entries"); for (auto kv : entries) m_parent.attr(kv.first) = kv.second[int_(0)]; @@ -1874,7 +1874,7 @@ template class enum_ : public class_ { PYBIND11_NAMESPACE_BEGIN(detail) -PYBIND11_NOINLINE_DCL void keep_alive_impl(handle nurse, handle patient) { +PYBIND11_NOINLINE void keep_alive_impl(handle nurse, handle patient) { if (!nurse || !patient) pybind11_fail("Could not activate keep_alive!"); @@ -1901,7 +1901,7 @@ PYBIND11_NOINLINE_DCL void keep_alive_impl(handle nurse, handle patient) { } } -PYBIND11_NOINLINE_DCL void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret) { +PYBIND11_NOINLINE void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret) { auto get_arg = [&](size_t n) { if (n == 0) return ret; @@ -2151,7 +2151,7 @@ exception ®ister_local_exception(handle scope, } PYBIND11_NAMESPACE_BEGIN(detail) -PYBIND11_NOINLINE_DCL void print(const tuple &args, const dict &kwargs) { +PYBIND11_NOINLINE void print(const tuple &args, const dict &kwargs) { auto strings = tuple(args.size()); for (size_t i = 0; i < args.size(); ++i) { strings[i] = str(args[i]); diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 477a5cd221..ba19c18556 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -30,8 +30,8 @@ struct arg; struct arg_v; PYBIND11_NAMESPACE_BEGIN(detail) class args_proxy; -PYBIND11_NOINLINE_FWD bool isinstance_generic(handle obj, const std::type_info &tp); -PYBIND11_NOINLINE_FWD std::string error_string(); +bool isinstance_generic(handle obj, const std::type_info &tp); +std::string error_string(); // Accessor forward declarations template class accessor; From a304a25ef400e16cada9ee233d586d92fcec1ea9 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 3 Aug 2021 15:10:18 -0700 Subject: [PATCH 15/18] Testing with PYBIND11_NOINLINE_DISABLED. Minor non-functional enhancements. --- include/pybind11/detail/common.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 68af33fb53..15aa1d893f 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -56,9 +56,6 @@ # elif __INTEL_COMPILER < 1900 && defined(PYBIND11_CPP14) # error pybind11 supports only C++11 with Intel C++ compiler v18. Use v19 or newer for C++14. # endif -/* The following pragma cannot be pop'ed: - https://community.intel.com/t5/Intel-C-Compiler/Inline-and-no-inline-warning/td-p/1216764 */ -# pragma warning disable 2196 // warning #2196: routine is both "inline" and "noinline" #elif defined(__clang__) && !defined(__apple_build_version__) # if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3) # error pybind11 requires clang 3.3 or newer @@ -99,6 +96,8 @@ # endif #endif +#define PYBIND11_NOINLINE_DISABLED + // For CUDA, GCC7, GCC8 (and maybe some other platforms): // PYBIND11_NOINLINE_FORCED is incompatible with `-Wattributes -Werror`. // When defining PYBIND11_NOINLINE_FORCED, it is best to also use @@ -109,7 +108,7 @@ # define PYBIND11_NOINLINE_DISABLED #endif -// Note: Forward declaration should never be `inline`: +// Note: Forward declarations should never be `inline`: // https://stackoverflow.com/questions/9317473/forward-declaration-of-inline-functions #if defined(PYBIND11_NOINLINE_DISABLED) # define PYBIND11_NOINLINE inline @@ -124,11 +123,15 @@ // This code and the 9 x 2 pragma blocks referring to // PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED could be purged. // ---------------------------------------------------------------------------- -#if !defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) && \ - !defined(PYBIND11_NOINLINE_DISABLED) && \ - (defined(__CUDACC__) || \ - (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8))) -# define PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED +#if !defined(PYBIND11_NOINLINE_DISABLED) +# if (defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8))) \ + && !defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED) +# define PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED +# elif defined(__INTEL_COMPILER) +// The following pragma cannot be pop'ed: +// https://community.intel.com/t5/Intel-C-Compiler/Inline-and-no-inline-warning/td-p/1216764 +# pragma warning disable 2196 // warning #2196: routine is both "inline" and "noinline" +# endif #endif #if defined(__MINGW32__) From 2fade636731afb1661236e12c69ba3620acc3b8d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 3 Aug 2021 17:20:15 -0700 Subject: [PATCH 16/18] Removing #define PYBIND11_NOINLINE_DISABLED (test was successful). --- include/pybind11/detail/common.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 15aa1d893f..890ebc7251 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -96,8 +96,6 @@ # endif #endif -#define PYBIND11_NOINLINE_DISABLED - // For CUDA, GCC7, GCC8 (and maybe some other platforms): // PYBIND11_NOINLINE_FORCED is incompatible with `-Wattributes -Werror`. // When defining PYBIND11_NOINLINE_FORCED, it is best to also use From af0d4ca348dfae5104644fc223a5e5f6f88f79bf Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 9 Aug 2021 11:48:02 -0700 Subject: [PATCH 17/18] Fixing up after git rebase -X theirs master --- include/pybind11/detail/common.h | 5 +++-- include/pybind11/pytypes.h | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 890ebc7251..159cf96116 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -106,9 +106,10 @@ # define PYBIND11_NOINLINE_DISABLED #endif -// Note: Forward declarations should never be `inline`: +// The PYBIND11_NOINLINE macro is for function DEFINITIONS. +// In contrast, FORWARD DECLARATIONS should never use this macro: // https://stackoverflow.com/questions/9317473/forward-declaration-of-inline-functions -#if defined(PYBIND11_NOINLINE_DISABLED) +#if defined(PYBIND11_NOINLINE_DISABLED) // Option for maximum portability and experimentation. # define PYBIND11_NOINLINE inline #elif defined(_MSC_VER) # define PYBIND11_NOINLINE __declspec(noinline) inline diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index ba19c18556..e6d985630b 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -28,10 +28,8 @@ class type; struct arg; struct arg_v; PYBIND11_NAMESPACE_BEGIN(detail) - class args_proxy; bool isinstance_generic(handle obj, const std::type_info &tp); -std::string error_string(); // Accessor forward declarations template class accessor; @@ -322,6 +320,10 @@ template T reinterpret_borrow(handle h) { return {h, object::borrow \endrst */ template T reinterpret_steal(handle h) { return {h, object::stolen_t{}}; } +PYBIND11_NAMESPACE_BEGIN(detail) +std::string error_string(); +PYBIND11_NAMESPACE_END(detail) + #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable: 4275 4251) // warning C4275: An exported class was derived from a class that wasn't exported. Can be ignored when derived from a STL class. From bec4e6d2db331fe51a886ddd04fabf69a40ba945 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 9 Aug 2021 11:53:06 -0700 Subject: [PATCH 18/18] Removing PYBIND11_NOINLINE_FORCED (to be moved to an alternative PR). --- include/pybind11/detail/common.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 159cf96116..8b06d771b2 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -96,16 +96,6 @@ # endif #endif -// For CUDA, GCC7, GCC8 (and maybe some other platforms): -// PYBIND11_NOINLINE_FORCED is incompatible with `-Wattributes -Werror`. -// When defining PYBIND11_NOINLINE_FORCED, it is best to also use -// `-Wno-attributes` (or not to use `-Werror` and ignore the warnings). -#if !defined(PYBIND11_NOINLINE_FORCED) && \ - (defined(__CUDACC__) || \ - (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8))) -# define PYBIND11_NOINLINE_DISABLED -#endif - // The PYBIND11_NOINLINE macro is for function DEFINITIONS. // In contrast, FORWARD DECLARATIONS should never use this macro: // https://stackoverflow.com/questions/9317473/forward-declaration-of-inline-functions @@ -117,11 +107,6 @@ # define PYBIND11_NOINLINE __attribute__ ((noinline)) inline #endif -// DECISION TO BE MADE before this PR is merged: -// ---------------------------------------------------------------------------- -// This code and the 9 x 2 pragma blocks referring to -// PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED could be purged. -// ---------------------------------------------------------------------------- #if !defined(PYBIND11_NOINLINE_DISABLED) # if (defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8))) \ && !defined(PYBIND11_NOINLINE_GCC_PRAGMA_ATTRIBUTES_NEEDED)