Skip to content

Commit

Permalink
Fix ODR issue in type_caster which could result in UB when -flto is…
Browse files Browse the repository at this point in the history
… enabled (#1028)

Closes #976 

One could expose the issue (before the fix) on macOS after installing
gcc-14 with homebrew with the command
`CXX=gcc-14 python -m build -w`
  • Loading branch information
HDembinski authored Aug 25, 2024
1 parent abff499 commit 18a6d08
Show file tree
Hide file tree
Showing 28 changed files with 59 additions and 50 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ __pycache__
*.o
*.pkl

CMakeCache.txt
CMakeFiles/

pip-wheel-metadata

bench/*.svg
Expand Down
26 changes: 18 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ if(NOT DEFINED SKBUILD)
)
endif()

include(CheckIPOSupported)
check_ipo_supported(RESULT ipo_supported OUTPUT error)

set(CMAKE_CXX_STANDARD
14
CACHE STRING "C++ version selection") # or 11, 14, 17, 20
set(CMAKE_CXX_STANDARD_REQUIRED ON) # optional, ensure standard is supported
set(CMAKE_CXX_EXTENSIONS OFF) # optional, keep compiler extensionsn off

set(PYBIND11_FINDPYTHON ON)
find_package(pybind11 CONFIG REQUIRED)

Expand Down Expand Up @@ -84,6 +86,15 @@ set(SOURCES_B
extern/root/math/minuit2/src/mnxerbla.cxx)

pybind11_add_module(_core MODULE ${SOURCES_A} ${SOURCES_B})

target_include_directories(_core PRIVATE extern/root/math/minuit2/inc)
target_compile_definitions(_core PUBLIC PYBIND11_DETAILED_ERROR_MESSAGES=1)
set_target_properties(_core PROPERTIES VISIBILITY_INLINES_HIDDEN ON)
if(ipo_supported)
set_target_properties(_core PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()

# Add compiler-specific extra warnings
if(MSVC)
target_compile_options(_core PRIVATE /std:c++14 /Y-)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
Expand All @@ -92,19 +103,18 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
_core
PRIVATE -Wall
-Wextra
-pedantic
-Werror
-fstrict-aliasing
-Werror=odr
-Werror=lto-type-mismatch
-Werror=strict-aliasing)
-Werror=strict-aliasing
-pedantic
-fstrict-aliasing)
target_link_options(_core PRIVATE -Werror -Wodr -Wlto-type-mismatch)
else()
# lots of warnings from clang
target_compile_options(_core PRIVATE -Wall -Wextra -pedantic -Werror
-fstrict-aliasing)
-Werror=odr -fstrict-aliasing)
target_link_options(_core PRIVATE -Werror -Wodr)
endif()
target_include_directories(_core PRIVATE extern/root/math/minuit2/inc)
set_target_properties(_core PROPERTIES VISIBILITY_INLINES_HIDDEN ON)
target_compile_definitions(_core PUBLIC PYBIND11_DETAILED_ERROR_MESSAGES=1)

install(TARGETS _core DESTINATION iminuit)
2 changes: 1 addition & 1 deletion extern/root
Submodule root updated 1676 files
2 changes: 1 addition & 1 deletion src/application.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "pybind11.hpp"
#include <Minuit2/FunctionMinimum.h>
#include <Minuit2/MnApplication.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;
using namespace ROOT::Minuit2;
Expand Down
3 changes: 1 addition & 2 deletions src/contours.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#include "pybind11.hpp"
#include <Minuit2/ContoursError.h>
#include <Minuit2/FCNBase.h>
#include <Minuit2/FunctionMinimum.h>
#include <Minuit2/MnContours.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

namespace py = pybind11;
using namespace ROOT::Minuit2;
Expand Down
4 changes: 1 addition & 3 deletions src/fcn.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
#include "fcn.hpp"
#include "type_caster.hpp"
#include "pybind11.hpp"
#include <Minuit2/FCNGradientBase.h>
#include <Minuit2/MnPrint.h>
#include <cmath>
#include <cstdint>
#include <limits>
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>
#include <sstream>
#include <vector>

Expand Down
2 changes: 1 addition & 1 deletion src/fcn.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "pybind11.hpp"
#include <Minuit2/FCNGradientBase.h>
#include <cstdint>
#include <pybind11/pytypes.h>
#include <vector>

namespace py = pybind11;
Expand Down
5 changes: 1 addition & 4 deletions src/functionminimum.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
#include "equal.hpp"
#include "fcn.hpp"
#include "pybind11.hpp"
#include <Minuit2/FunctionMinimum.h>
#include <Minuit2/MinimumSeed.h>
#include <Minuit2/MinimumState.h>
#include <Minuit2/MnStrategy.h>
#include <Minuit2/MnUserFcn.h>
#include <Minuit2/MnUserParameterState.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <type_traits>
#include <vector>

namespace py = pybind11;
using namespace ROOT::Minuit2;
Expand Down
2 changes: 1 addition & 1 deletion src/functionminimum_extra.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "equal.hpp"
#include "fcn.hpp"
#include "pybind11.hpp"
#include <Minuit2/AnalyticalGradientCalculator.h>
#include <Minuit2/FunctionMinimum.h>
#include <Minuit2/MinimumState.h>
Expand All @@ -10,7 +11,6 @@
#include <Minuit2/MnUserParameterState.h>
#include <Minuit2/Numerical2PGradientCalculator.h>
#include <Minuit2/VariableMetricEDMEstimator.h>
#include <pybind11/pybind11.h>
#include <type_traits>
#include <vector>

Expand Down
3 changes: 1 addition & 2 deletions src/functionminimum_pickle.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#include "pybind11.hpp"
#include <Minuit2/FunctionMinimum.h>
#include <Minuit2/MinimumSeed.h>
#include <Minuit2/MinimumState.h>
#include <Minuit2/MnUserParameterState.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <type_traits>
#include <vector>

Expand Down
2 changes: 1 addition & 1 deletion src/hesse.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "pybind11.hpp"
#include <Minuit2/FCNBase.h>
#include <Minuit2/FunctionMinimum.h>
#include <Minuit2/MnHesse.h>
#include <Minuit2/MnUserFcn.h>
#include <Minuit2/MnUserParameterState.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;
using namespace ROOT::Minuit2;
Expand Down
2 changes: 1 addition & 1 deletion src/lasymmatrix.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef IMINUIT_LASYMMATRIX
#define IMINUIT_LASYMMATRIX

#include "pybind11.hpp"
#include <Minuit2/LASymMatrix.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;
using namespace ROOT::Minuit2;
Expand Down
2 changes: 1 addition & 1 deletion src/lavector.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef IMINUIT_LAVECTOR
#define IMINUIT_LAVECTOR

#include "pybind11.hpp"
#include <Minuit2/LAVector.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;
using namespace ROOT::Minuit2;
Expand Down
3 changes: 1 addition & 2 deletions src/machineprecision.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "pybind11.hpp"
#include <Minuit2/MnMachinePrecision.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>

namespace ROOT {
namespace Minuit2 {
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include <pybind11/pybind11.h>
#include "pybind11.hpp"

namespace py = pybind11;

Expand Down
2 changes: 1 addition & 1 deletion src/migrad.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "fcn.hpp"
#include "pybind11.hpp"
#include <Minuit2/FCNBase.h>
#include <Minuit2/MnMigrad.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;
using namespace ROOT::Minuit2;
Expand Down
2 changes: 0 additions & 2 deletions src/minimumstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
#include "lavector.hpp"
#include <Minuit2/MinimumState.h>
#include <cmath>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <type_traits>

namespace py = pybind11;
Expand Down
2 changes: 1 addition & 1 deletion src/minos.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "pybind11.hpp"
#include <Minuit2/FCNBase.h>
#include <Minuit2/FunctionMinimum.h>
#include <Minuit2/MinosError.h>
#include <Minuit2/MnMinos.h>
#include <Minuit2/MnStrategy.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;
using namespace ROOT::Minuit2;
Expand Down
3 changes: 1 addition & 2 deletions src/minuitparameter.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "equal.hpp"
#include "pybind11.hpp"
#include <Minuit2/MinuitParameter.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>

namespace ROOT {
namespace Minuit2 {
Expand Down
2 changes: 1 addition & 1 deletion src/print.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "pybind11.hpp"
#include <Minuit2/MnPrint.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;
using namespace ROOT::Minuit2;
Expand Down
2 changes: 1 addition & 1 deletion src/printimpl.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "Minuit2/MnPrint.h"
#include <pybind11/pybind11.h>
#include "pybind11.hpp"

using ROOT::Minuit2::MnPrint;

Expand Down
15 changes: 14 additions & 1 deletion src/type_caster.hpp → src/pybind11.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
#ifndef PYBIND11_HPP
#define PYBIND11_HPP

// We must load pybind11 consistently through this header to ensure that our type_caster
// specialization is used in every translation unit. Otherwise we get ODR violations.

#include <pybind11/numpy.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/pytypes.h>
#include <pybind11/stl.h>
#include <vector>

namespace pybind11 {
namespace detail {

// This specialization for vector<double> acts as an override from the more generic
// template in pybind11/stl.h. We use it to cast the C++ vector into a numpy array
// instead of a Python list.
template <>
struct type_caster<std::vector<double>> {
using vec_t = std::vector<double>;
Expand All @@ -27,7 +39,6 @@ struct type_caster<std::vector<double>> {
return false;
}

public:
template <typename T>
static handle cast(T&& src, return_value_policy, handle) {
array_t<double> arr(static_cast<ssize_t>(src.size()));
Expand All @@ -40,3 +51,5 @@ struct type_caster<std::vector<double>> {

} // namespace detail
} // namespace pybind11

#endif // PYBIND11_HPP
2 changes: 1 addition & 1 deletion src/scan.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "pybind11.hpp"
#include <Minuit2/FCNBase.h>
#include <Minuit2/MnScan.h>
#include <Minuit2/MnUserParameterState.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;
using namespace ROOT::Minuit2;
Expand Down
2 changes: 1 addition & 1 deletion src/simplex.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "fcn.hpp"
#include "pybind11.hpp"
#include <Minuit2/FCNBase.h>
#include <Minuit2/MnSimplex.h>
#include <pybind11/pybind11.h>

namespace py = pybind11;
using namespace ROOT::Minuit2;
Expand Down
3 changes: 1 addition & 2 deletions src/strategy.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "equal.hpp"
#include "pybind11.hpp"
#include <Minuit2/MnStrategy.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>

namespace ROOT {
namespace Minuit2 {
Expand Down
4 changes: 1 addition & 3 deletions src/usercovariance.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#include "equal.hpp"
#include "type_caster.hpp"
#include "pybind11.hpp"
#include <Minuit2/MnUserCovariance.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <vector>

namespace ROOT {
Expand Down
4 changes: 1 addition & 3 deletions src/userparameterstate.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#include "equal.hpp"
#include "type_caster.hpp"
#include "pybind11.hpp"
#include <Minuit2/MnUserParameterState.h>
#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <type_traits>

namespace ROOT {
Expand Down
3 changes: 1 addition & 2 deletions src/usertransformation.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "pybind11.hpp"
#include <Minuit2/MnUserTransformation.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <type_traits>

namespace py = pybind11;
Expand Down

0 comments on commit 18a6d08

Please # to comment.