From 88281794c766613b61a4659c2814af5ea524c492 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Mon, 27 Apr 2026 20:22:25 +0200 Subject: [PATCH 01/39] Add MSVC native cl.exe build support - Remove dead `exx_coeff` static constexpr in `deorbitalized.hpp` that referenced non-existent members in kernel_traits (MSVC eagerly instantiates it; GCC/Clang deferred since it was never ODR-used) - Replace C++ alternative operator tokens (`not`, `and`, `or`) with standard `!`, `&&`, `||` across headers and source files (MSVC cl.exe does not recognize them without /permissive-) - Add `_USE_MATH_DEFINES` compile definition for MSVC (M_PI) - Suppress MSVC warning C4800 (implicit double-to-bool conversion in auto-generated kernel code) - Replace `sed` PATCH_COMMAND for libxc with portable CMake -P script so FetchContent works on Windows without Unix tools --- CMakeLists.txt | 2 +- cmake/patch_libxc_work_mgga.cmake | 13 ++++++++++ .../exchcxx/exceptions/exchcxx_exception.hpp | 2 +- .../impl/builtin/kernels/deorbitalized.hpp | 1 - .../builtin/kernels/screening_interface.hpp | 16 ++++++------- include/exchcxx/xc_functional.hpp | 6 ++--- src/CMakeLists.txt | 3 +++ src/builtin_interface.cxx | 2 +- src/libxc.cxx | 8 +++---- src/xc_functional.cxx | 24 +++++++++---------- 10 files changed, 46 insertions(+), 31 deletions(-) create mode 100644 cmake/patch_libxc_work_mgga.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 92eca2a..ac57e85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,7 +81,7 @@ else() # if pinning to specific SHA change the FETCHCONTENT_LIBXC_GIT_SHALLOW default to OFF, https://cmake.org/cmake/help/latest/module/ExternalProject.html#git GIT_TAG 7.0.0 GIT_SHALLOW ${FETCHCONTENT_LIBXC_GIT_SHALLOW} - PATCH_COMMAND sed -i -e "s/p->info->family != XC_KINETIC/p->info->kind != XC_KINETIC/g" src/work_mgga_inc.c + PATCH_COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/cmake/patch_libxc_work_mgga.cmake" ) set( Libxc_VERSION 7.0.0 ) diff --git a/cmake/patch_libxc_work_mgga.cmake b/cmake/patch_libxc_work_mgga.cmake new file mode 100644 index 0000000..eaf2d7a --- /dev/null +++ b/cmake/patch_libxc_work_mgga.cmake @@ -0,0 +1,13 @@ +# patch_libxc_work_mgga.cmake +# Portable replacement for: +# sed -i -e "s/p->info->family != XC_KINETIC/p->info->kind != XC_KINETIC/g" src/work_mgga_inc.c +# Run from the libxc source directory via PATCH_COMMAND. + +set(_file "src/work_mgga_inc.c") +if(NOT EXISTS "${_file}") + message(FATAL_ERROR "patch_libxc_work_mgga.cmake: ${_file} not found (cwd=${CMAKE_CURRENT_SOURCE_DIR})") +endif() + +file(READ "${_file}" _content) +string(REPLACE "p->info->family != XC_KINETIC" "p->info->kind != XC_KINETIC" _content "${_content}") +file(WRITE "${_file}" "${_content}") diff --git a/include/exchcxx/exceptions/exchcxx_exception.hpp b/include/exchcxx/exceptions/exchcxx_exception.hpp index 6d6563f..ea154c1 100644 --- a/include/exchcxx/exceptions/exchcxx_exception.hpp +++ b/include/exchcxx/exceptions/exchcxx_exception.hpp @@ -77,7 +77,7 @@ class exchcxx_exception : public std::exception { }; #define EXCHCXX_BOOL_CHECK( MSG, V ) \ - if( not (V) ) \ + if( !(V) ) \ throw exchcxx_exception( __FILE__, __LINE__, MSG ); } diff --git a/include/exchcxx/impl/builtin/kernels/deorbitalized.hpp b/include/exchcxx/impl/builtin/kernels/deorbitalized.hpp index e00bc23..e31a41e 100644 --- a/include/exchcxx/impl/builtin/kernels/deorbitalized.hpp +++ b/include/exchcxx/impl/builtin/kernels/deorbitalized.hpp @@ -70,7 +70,6 @@ struct kernel_traits> { static constexpr bool needs_laplacian = true; static constexpr bool is_kedf = false; static constexpr bool is_epc = false; - static constexpr double exx_coeff = xc_traits::exx_coeff + ke_traits::exx_coeff; BUILTIN_KERNEL_EVAL_RETURN eval_exc_unpolar( double rho, double sigma, double lapl, double tau, double& eps ) { diff --git a/include/exchcxx/impl/builtin/kernels/screening_interface.hpp b/include/exchcxx/impl/builtin/kernels/screening_interface.hpp index e34b775..a34c2f6 100644 --- a/include/exchcxx/impl/builtin/kernels/screening_interface.hpp +++ b/include/exchcxx/impl/builtin/kernels/screening_interface.hpp @@ -394,7 +394,7 @@ struct mgga_screening_interface { constexpr auto sigma_tol_sq = traits::sigma_tol * traits::sigma_tol; sigma = safe_max(sigma, sigma_tol_sq); tau = safe_max(tau, traits::tau_tol); - if constexpr (not traits::is_kedf) { + if constexpr (!traits::is_kedf) { sigma = enforce_fermi_hole_curvature(sigma, rho, tau); } @@ -421,7 +421,7 @@ struct mgga_screening_interface { sigma_bb = safe_max(sigma_bb, sigma_tol_sq); tau_a = safe_max(tau_a, traits::tau_tol); tau_b = safe_max(tau_b, traits::tau_tol); - if constexpr (not traits::is_kedf) { + if constexpr (!traits::is_kedf) { sigma_aa = enforce_fermi_hole_curvature(sigma_aa, rho_a, tau_a); sigma_bb = enforce_fermi_hole_curvature(sigma_bb, rho_b, tau_b); } @@ -450,7 +450,7 @@ struct mgga_screening_interface { constexpr auto sigma_tol_sq = traits::sigma_tol * traits::sigma_tol; sigma = safe_max(sigma, sigma_tol_sq); tau = safe_max(tau, traits::tau_tol); - if constexpr (not traits::is_kedf) { + if constexpr (!traits::is_kedf) { sigma = enforce_fermi_hole_curvature(sigma, rho, tau); } traits::eval_exc_vxc_unpolar_impl(rho, sigma, lapl, tau, @@ -489,7 +489,7 @@ struct mgga_screening_interface { sigma_bb = safe_max(sigma_bb, sigma_tol_sq); tau_a = safe_max(tau_a, traits::tau_tol); tau_b = safe_max(tau_b, traits::tau_tol); - if constexpr (not traits::is_kedf) { + if constexpr (!traits::is_kedf) { sigma_aa = enforce_fermi_hole_curvature(sigma_aa, rho_a, tau_a); sigma_bb = enforce_fermi_hole_curvature(sigma_bb, rho_b, tau_b); } @@ -519,7 +519,7 @@ BUILTIN_KERNEL_EVAL_RETURN constexpr auto sigma_tol_sq = traits::sigma_tol * traits::sigma_tol; sigma = safe_max(sigma, sigma_tol_sq); tau = safe_max(tau, traits::tau_tol); - if constexpr (not traits::is_kedf) { + if constexpr (!traits::is_kedf) { sigma = enforce_fermi_hole_curvature(sigma, rho, tau); } traits::eval_fxc_unpolar_impl(rho, sigma, lapl, tau, @@ -575,7 +575,7 @@ BUILTIN_KERNEL_EVAL_RETURN sigma_bb = safe_max(sigma_bb, sigma_tol_sq); tau_a = safe_max(tau_a, traits::tau_tol); tau_b = safe_max(tau_b, traits::tau_tol); - if constexpr (not traits::is_kedf) { + if constexpr (!traits::is_kedf) { sigma_aa = enforce_fermi_hole_curvature(sigma_aa, rho_a, tau_a); sigma_bb = enforce_fermi_hole_curvature(sigma_bb, rho_b, tau_b); } @@ -621,7 +621,7 @@ BUILTIN_KERNEL_EVAL_RETURN sigma = safe_max(sigma, sigma_tol_sq); tau = safe_max(tau, traits::tau_tol); - if constexpr (not traits::is_kedf) { + if constexpr (!traits::is_kedf) { sigma = enforce_fermi_hole_curvature(sigma, rho, tau); } @@ -686,7 +686,7 @@ BUILTIN_KERNEL_EVAL_RETURN tau_a = safe_max(tau_a, traits::tau_tol); tau_b = safe_max(tau_b, traits::tau_tol); - if constexpr (not traits::is_kedf) { + if constexpr (!traits::is_kedf) { sigma_aa = enforce_fermi_hole_curvature(sigma_aa, rho_a, tau_a); sigma_bb = enforce_fermi_hole_curvature(sigma_bb, rho_b, tau_b); } diff --git a/include/exchcxx/xc_functional.hpp b/include/exchcxx/xc_functional.hpp index 838e6e6..62d952e 100644 --- a/include/exchcxx/xc_functional.hpp +++ b/include/exchcxx/xc_functional.hpp @@ -92,7 +92,7 @@ class XCFunctional { inline bool sanity_check() const { // Must have one kernel - if( not kernels_.size() ) return false; + if( !kernels_.size() ) return false; // Polarization is all or nothing int polar_one = kernels_.at(0).second.is_polarized(); @@ -103,7 +103,7 @@ class XCFunctional { } ); - if( not polar_all ) return false; + if( !polar_all ) return false; // If we made it, kernel is sane return true; @@ -164,7 +164,7 @@ class XCFunctional { return std::any_of( kernels_.begin(), kernels_.end(), [](const auto& x) { return x.second.is_gga(); } - ) and not is_mgga(); + ) && !is_mgga(); } inline bool is_mgga() const { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ec0adad..87a5cc3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,9 @@ add_library( exchcxx ${EXCHCXX_SOURCES} ) # TARGET properties target_compile_features( exchcxx PUBLIC cxx_std_17 ) +if(MSVC) + target_compile_definitions( exchcxx PUBLIC _USE_MATH_DEFINES ) +endif() if( EXCHCXX_ENABLE_LIBXC ) target_link_libraries( exchcxx PUBLIC Libxc::xc ) endif() diff --git a/src/builtin_interface.cxx b/src/builtin_interface.cxx index 3ad7ce2..03a757b 100644 --- a/src/builtin_interface.cxx +++ b/src/builtin_interface.cxx @@ -67,7 +67,7 @@ std::unique_ptr // Bail if polarized eval is requested and not supported EXCHCXX_BOOL_CHECK(kernel_map.key(kern) + " Needs to be Spin-Polarized!", - supports_unpolarized(kern) or polar == Spin::Polarized); + supports_unpolarized(kern) || polar == Spin::Polarized); if( kern == Kernel::SlaterExchange ) return std::make_unique( polar ); diff --git a/src/libxc.cxx b/src/libxc.cxx index fb859bd..8d6b9e6 100644 --- a/src/libxc.cxx +++ b/src/libxc.cxx @@ -256,7 +256,7 @@ std::unique_ptr< XCKernelImpl > LibxcKernelImpl::clone_() const { bool LibxcKernelImpl::is_lda_() const noexcept { return (kernel_.info->family == XC_FAMILY_LDA) #if XC_MAJOR_VERSION > 6 - or (kernel_.info->family == XC_FAMILY_HYB_LDA) + || (kernel_.info->family == XC_FAMILY_HYB_LDA) #endif ; } @@ -264,13 +264,13 @@ bool LibxcKernelImpl::is_lda_() const noexcept { bool LibxcKernelImpl::is_gga_() const noexcept { return (kernel_.info->family == XC_FAMILY_GGA ) - or (kernel_.info->family == XC_FAMILY_HYB_GGA); + || (kernel_.info->family == XC_FAMILY_HYB_GGA); } bool LibxcKernelImpl::is_mgga_() const noexcept { return (kernel_.info->family == XC_FAMILY_MGGA ) - or (kernel_.info->family == XC_FAMILY_HYB_MGGA); + || (kernel_.info->family == XC_FAMILY_HYB_MGGA); } bool LibxcKernelImpl::needs_laplacian_() const noexcept { @@ -294,7 +294,7 @@ bool LibxcKernelImpl::is_epc_() const noexcept { int xcNumber = xc_info()->number; return #if XC_MAJOR_VERSION > 7 - xcNumber == XC_LDA_C_EPC17 or xcNumber == XC_LDA_C_EPC17_2 or xcNumber == XC_LDA_C_EPC18_1 or xcNumber == XC_LDA_C_EPC18_2; + xcNumber == XC_LDA_C_EPC17 || xcNumber == XC_LDA_C_EPC17_2 || xcNumber == XC_LDA_C_EPC18_1 || xcNumber == XC_LDA_C_EPC18_2; #else false; #endif diff --git a/src/xc_functional.cxx b/src/xc_functional.cxx index 24f99b4..6acfe02 100644 --- a/src/xc_functional.cxx +++ b/src/xc_functional.cxx @@ -711,7 +711,7 @@ LDA_EXC_GENERATOR( XCFunctional::eval_exc ) const { const size_t len_exc_buffer = exc_buffer_len(N); std::vector eps_scr; - if( kernels_.size() > 1 and not supports_inc_interface() ) + if( kernels_.size() > 1 && !supports_inc_interface() ) eps_scr.resize( len_exc_buffer ); std::fill_n( eps, len_exc_buffer, 0. ); @@ -749,7 +749,7 @@ LDA_EXC_VXC_GENERATOR( XCFunctional::eval_exc_vxc ) const { const size_t len_vxc_buffer = vrho_buffer_len(N); std::vector eps_scr, vxc_scr; - if( kernels_.size() > 1 and not supports_inc_interface() ) { + if( kernels_.size() > 1 && !supports_inc_interface() ) { eps_scr.resize( len_exc_buffer ); vxc_scr.resize( len_vxc_buffer ); } @@ -869,7 +869,7 @@ GGA_EXC_GENERATOR( XCFunctional::eval_exc ) const { const size_t len_exc_buffer = exc_buffer_len(N); std::vector eps_scr; - if( kernels_.size() > 1 and not supports_inc_interface() ) + if( kernels_.size() > 1 && !supports_inc_interface() ) eps_scr.resize( len_exc_buffer ); std::fill_n( eps, len_exc_buffer, 0. ); @@ -919,7 +919,7 @@ GGA_EXC_VXC_GENERATOR( XCFunctional::eval_exc_vxc ) const { const size_t len_vsigma_buffer = vsigma_buffer_len(N); std::vector eps_scr, vrho_scr, vsigma_scr; - if( kernels_.size() > 1 and not supports_inc_interface() ) { + if( kernels_.size() > 1 && !supports_inc_interface() ) { eps_scr.resize( len_exc_buffer ); vrho_scr.resize( len_vrho_buffer ); vsigma_scr.resize( len_vsigma_buffer ); @@ -988,7 +988,7 @@ GGA_FXC_GENERATOR( XCFunctional::eval_fxc ) const { const size_t len_v2sigma2_buffer = v2sigma2_buffer_len(N); std::vector v2sigma2_scr, v2rhosigma_scr, v2rho2_scr; - if( kernels_.size() > 1 and not supports_inc_interface() ) { + if( kernels_.size() > 1 && !supports_inc_interface() ) { v2rho2_scr.resize( len_v2rho2_buffer ); v2rhosigma_scr.resize( len_v2rhosigma_buffer ); v2sigma2_scr.resize( len_v2sigma2_buffer ); @@ -1053,7 +1053,7 @@ GGA_VXC_FXC_GENERATOR( XCFunctional::eval_vxc_fxc ) const { const size_t len_v2sigma2_buffer = v2sigma2_buffer_len(N); std::vector vrho_scr, vsigma_scr, v2rho2_scr, v2rhosigma_scr, v2sigma2_scr; - if( kernels_.size() > 1 and not supports_inc_interface() ) { + if( kernels_.size() > 1 && !supports_inc_interface() ) { vrho_scr.resize( len_vrho_buffer ); vsigma_scr.resize( len_vsigma_buffer ); v2rho2_scr.resize( len_v2rho2_buffer ); @@ -1130,7 +1130,7 @@ MGGA_EXC_GENERATOR( XCFunctional::eval_exc ) const { const size_t len_exc_buffer = exc_buffer_len(N); std::vector eps_scr; - if( kernels_.size() > 1 and not supports_inc_interface() ) + if( kernels_.size() > 1 && !supports_inc_interface() ) eps_scr.resize( len_exc_buffer ); std::fill_n( eps, len_exc_buffer, 0. ); @@ -1188,7 +1188,7 @@ MGGA_EXC_VXC_GENERATOR( XCFunctional::eval_exc_vxc ) const { const size_t len_vtau_buffer = vtau_buffer_len(N); std::vector eps_scr, vrho_scr, vsigma_scr, vlapl_scr, vtau_scr; - if( kernels_.size() > 1 and not supports_inc_interface() ) { + if( kernels_.size() > 1 && !supports_inc_interface() ) { eps_scr.resize( len_exc_buffer ); vrho_scr.resize( len_vrho_buffer ); vsigma_scr.resize( len_vsigma_buffer ); @@ -1244,7 +1244,7 @@ MGGA_EXC_VXC_GENERATOR( XCFunctional::eval_exc_vxc ) const { _addscal( len_exc_buffer, kernels_[i].first, eps, eps_eval ); _addscal( len_vrho_buffer, kernels_[i].first, vrho, vrho_eval ); - if( kernels_[i].second.is_gga() or kernels_[i].second.is_mgga() ) + if( kernels_[i].second.is_gga() || kernels_[i].second.is_mgga() ) _addscal( len_vsigma_buffer, kernels_[i].first, vsigma, vsigma_eval ); if( kernels_[i].second.needs_laplacian() ) @@ -1258,7 +1258,7 @@ MGGA_EXC_VXC_GENERATOR( XCFunctional::eval_exc_vxc ) const { _scal( len_exc_buffer, kernels_[i].first, eps ); _scal( len_vrho_buffer, kernels_[i].first, vrho ); - if( kernels_[i].second.is_gga() or kernels_[i].second.is_mgga() ) + if( kernels_[i].second.is_gga() || kernels_[i].second.is_mgga() ) _scal( len_vsigma_buffer, kernels_[i].first, vsigma ); if( kernels_[i].second.needs_laplacian() ) @@ -1361,7 +1361,7 @@ MGGA_FXC_GENERATOR( XCFunctional::eval_fxc ) const { if (i) { _addscal(len_v2rho2_buffer, kernels_[i].first, v2rho2, v2rho2_eval); - if( kernels_[i].second.is_gga() or kernels_[i].second.is_mgga() ){ + if( kernels_[i].second.is_gga() || kernels_[i].second.is_mgga() ){ _addscal(len_v2rhosigma_buffer, kernels_[i].first, v2rhosigma, v2rhosigma_eval); _addscal(len_v2sigma2_buffer, kernels_[i].first, v2sigma2, v2sigma2_eval); } @@ -1384,7 +1384,7 @@ MGGA_FXC_GENERATOR( XCFunctional::eval_fxc ) const { _scal(len_v2rho2_buffer, kernels_[i].first, v2rho2); - if (kernels_[i].second.is_gga() or kernels_[i].second.is_mgga()) { + if (kernels_[i].second.is_gga() || kernels_[i].second.is_mgga()) { _scal(len_v2rhosigma_buffer, kernels_[i].first, v2rhosigma); _scal(len_v2sigma2_buffer, kernels_[i].first, v2sigma2); } From 38299954a3a1b870913b821bd430e5cc0154a390 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Mon, 27 Apr 2026 21:55:07 +0200 Subject: [PATCH 02/39] Silence noisy MSVC warnings Co-authored-by: Copilot --- src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 87a5cc3..dd19e47 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,6 +18,7 @@ add_library( exchcxx ${EXCHCXX_SOURCES} ) target_compile_features( exchcxx PUBLIC cxx_std_17 ) if(MSVC) target_compile_definitions( exchcxx PUBLIC _USE_MATH_DEFINES ) + target_compile_options( exchcxx PUBLIC /wd4003 /wd4061 /wd4244 /wd4266 /wd4267 /wd4365 /wd4514 /wd4267 /wd4710 /wd4711 /wd4800 /wd4820 /wd5246 ) endif() if( EXCHCXX_ENABLE_LIBXC ) target_link_libraries( exchcxx PUBLIC Libxc::xc ) From 7d83223e72e2eb1446af87546b75cb81cfeca719 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Mon, 4 May 2026 21:46:02 +0200 Subject: [PATCH 03/39] manage warnings --- src/CMakeLists.txt | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dd19e47..f6df974 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,7 +18,38 @@ add_library( exchcxx ${EXCHCXX_SOURCES} ) target_compile_features( exchcxx PUBLIC cxx_std_17 ) if(MSVC) target_compile_definitions( exchcxx PUBLIC _USE_MATH_DEFINES ) - target_compile_options( exchcxx PUBLIC /wd4003 /wd4061 /wd4244 /wd4266 /wd4267 /wd4365 /wd4514 /wd4267 /wd4710 /wd4711 /wd4800 /wd4820 /wd5246 ) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # clang-cl + target_compile_options( exchcxx PUBLIC + -Wno-c++98-compat + -Wno-c++98-compat-local-type-template-args + -Wno-c++98-compat-pedantic + -Wno-deprecated-declarations + -Wno-exit-time-destructors + -Wno-extra-semi + -Wno-extra-semi-stmt + -Wno-float-conversion + -Wno-float-equal + -Wno-global-constructors + -Wno-inconsistent-missing-destructor-override + -Wno-missing-prototypes + -Wno-missing-variable-declarations + -Wno-old-style-cast + -Wno-pre-c++14-compat + -Wno-pre-c++17-compat + -Wno-reserved-macro-identifier + -Wno-sign-conversion + -Wno-suggest-destructor-override + -Wno-switch-enum + -Wno-undefined-func-template + -Wno-unsafe-buffer-usage + -Wno-unsafe-buffer-usage-in-libc-call + -Wno-unused-macros + -Wno-unused-parameter + -Wno-unused-variable + ) + else() # cl + target_compile_options( exchcxx PUBLIC /wd4003 /wd4061 /wd4244 /wd4266 /wd4267 /wd4365 /wd4514 /wd4267 /wd4710 /wd4711 /wd4800 /wd4820 /wd5246 ) + endif() endif() if( EXCHCXX_ENABLE_LIBXC ) target_link_libraries( exchcxx PUBLIC Libxc::xc ) From a266e2ab6a23ab19bf92ce16f35e8d3d6956dd02 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Tue, 5 May 2026 12:21:19 +0200 Subject: [PATCH 04/39] avoid clang warning: strdup warning C4996: 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: _strdup. --- include/exchcxx/exceptions/exchcxx_exception.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/exchcxx/exceptions/exchcxx_exception.hpp b/include/exchcxx/exceptions/exchcxx_exception.hpp index ea154c1..2bfa065 100644 --- a/include/exchcxx/exceptions/exchcxx_exception.hpp +++ b/include/exchcxx/exceptions/exchcxx_exception.hpp @@ -66,7 +66,7 @@ class exchcxx_exception : public std::exception { auto msg = ss.str(); - return strdup( msg.c_str() ); + return _strdup( msg.c_str() ); } public: From 601f72eb668e0721a8452fc3eaff510f431946b0 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Tue, 5 May 2026 14:13:39 +0200 Subject: [PATCH 05/39] formatting --- src/CMakeLists.txt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f6df974..a29cd88 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,7 +48,21 @@ if(MSVC) -Wno-unused-variable ) else() # cl - target_compile_options( exchcxx PUBLIC /wd4003 /wd4061 /wd4244 /wd4266 /wd4267 /wd4365 /wd4514 /wd4267 /wd4710 /wd4711 /wd4800 /wd4820 /wd5246 ) + target_compile_options( exchcxx PUBLIC + /wd4003 # not enough actual parameters for macro 'identifier' + /wd4061 # enumerator 'enumerator' in switch of enum 'enumeration' is not explicitly handled by a case label + /wd4244 # conversion from 'type1' to 'type2', possible loss of data + /wd4266 # no override available for virtual member function from base 'class'; function is hidden + /wd4267 # conversion from 'size_t' to 'type', possible loss of data + /wd4365 # conversion from 'type1' to 'type2', signed/unsigned mismatch + /wd4514 # unreferenced inline function has been removed + /wd4267 # conversion from 'size_t' to 'type', possible loss of data + /wd4710 # function 'function' not inlined + /wd4711 # function 'function' selected for automatic inline expansion + /wd4800 # forcing value to bool 'true' or 'false' (performance warning) + /wd4820 # 'bytes' bytes padding added after construct 'member_name' + /wd5246 # C-style struct initialization may not be portable + ) endif() endif() if( EXCHCXX_ENABLE_LIBXC ) From 871fcc17a97bf3f914a6263454cb2280798f6629 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Tue, 26 May 2026 18:30:39 +0200 Subject: [PATCH 06/39] Revert strdup and silence warning --- include/exchcxx/exceptions/exchcxx_exception.hpp | 2 +- src/CMakeLists.txt | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/exchcxx/exceptions/exchcxx_exception.hpp b/include/exchcxx/exceptions/exchcxx_exception.hpp index 2bfa065..ea154c1 100644 --- a/include/exchcxx/exceptions/exchcxx_exception.hpp +++ b/include/exchcxx/exceptions/exchcxx_exception.hpp @@ -66,7 +66,7 @@ class exchcxx_exception : public std::exception { auto msg = ss.str(); - return _strdup( msg.c_str() ); + return strdup( msg.c_str() ); } public: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a29cd88..a1d0e6a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,7 +17,7 @@ add_library( exchcxx ${EXCHCXX_SOURCES} ) target_compile_features( exchcxx PUBLIC cxx_std_17 ) if(MSVC) - target_compile_definitions( exchcxx PUBLIC _USE_MATH_DEFINES ) + target_compile_definitions( exchcxx PUBLIC _USE_MATH_DEFINES _CRT_NONSTDC_NO_DEPRECATE ) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # clang-cl target_compile_options( exchcxx PUBLIC -Wno-c++98-compat @@ -56,7 +56,6 @@ if(MSVC) /wd4267 # conversion from 'size_t' to 'type', possible loss of data /wd4365 # conversion from 'type1' to 'type2', signed/unsigned mismatch /wd4514 # unreferenced inline function has been removed - /wd4267 # conversion from 'size_t' to 'type', possible loss of data /wd4710 # function 'function' not inlined /wd4711 # function 'function' selected for automatic inline expansion /wd4800 # forcing value to bool 'true' or 'false' (performance warning) From 3f417b303479c93094f5c206b8e723b749964b5b Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Wed, 27 May 2026 21:15:43 +0200 Subject: [PATCH 07/39] Revert "Revert strdup and silence warning" This reverts commit 871fcc17a97bf3f914a6263454cb2280798f6629. --- include/exchcxx/exceptions/exchcxx_exception.hpp | 2 +- src/CMakeLists.txt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/exchcxx/exceptions/exchcxx_exception.hpp b/include/exchcxx/exceptions/exchcxx_exception.hpp index ea154c1..2bfa065 100644 --- a/include/exchcxx/exceptions/exchcxx_exception.hpp +++ b/include/exchcxx/exceptions/exchcxx_exception.hpp @@ -66,7 +66,7 @@ class exchcxx_exception : public std::exception { auto msg = ss.str(); - return strdup( msg.c_str() ); + return _strdup( msg.c_str() ); } public: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a1d0e6a..a29cd88 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,7 +17,7 @@ add_library( exchcxx ${EXCHCXX_SOURCES} ) target_compile_features( exchcxx PUBLIC cxx_std_17 ) if(MSVC) - target_compile_definitions( exchcxx PUBLIC _USE_MATH_DEFINES _CRT_NONSTDC_NO_DEPRECATE ) + target_compile_definitions( exchcxx PUBLIC _USE_MATH_DEFINES ) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # clang-cl target_compile_options( exchcxx PUBLIC -Wno-c++98-compat @@ -56,6 +56,7 @@ if(MSVC) /wd4267 # conversion from 'size_t' to 'type', possible loss of data /wd4365 # conversion from 'type1' to 'type2', signed/unsigned mismatch /wd4514 # unreferenced inline function has been removed + /wd4267 # conversion from 'size_t' to 'type', possible loss of data /wd4710 # function 'function' not inlined /wd4711 # function 'function' selected for automatic inline expansion /wd4800 # forcing value to bool 'true' or 'false' (performance warning) From 466a1f27d7f5bcc9a20caeea8ab73fe4bb1806e1 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Wed, 27 May 2026 22:47:57 +0200 Subject: [PATCH 08/39] Fix portability and memory leak in exchcxx_exception::what() The previous implementation called _strdup() (MSVC-only; unknown to GCC/Clang on POSIX) on a stringstream result inside what(), which both broke portability and leaked the allocated C string on every call. Build the formatted message once in the constructor and store it as a std::string member; what() now returns its .c_str(). This removes the need for strdup entirely, fixes the leak, and makes what() truly noexcept (no allocation or stringstream work on the noexcept path). Also drop the now-unused include and move string parameters into members to avoid an extra copy. --- .../exchcxx/exceptions/exchcxx_exception.hpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/include/exchcxx/exceptions/exchcxx_exception.hpp b/include/exchcxx/exceptions/exchcxx_exception.hpp index 2bfa065..73837f2 100644 --- a/include/exchcxx/exceptions/exchcxx_exception.hpp +++ b/include/exchcxx/exceptions/exchcxx_exception.hpp @@ -47,7 +47,6 @@ #include #include -#include #include namespace ExchCXX { @@ -57,22 +56,22 @@ class exchcxx_exception : public std::exception { std::string file_; int line_; std::string msg_prefix_; + std::string what_msg_; const char* what() const noexcept override { - std::stringstream ss; - ss << "EXCHCXX Exception (" << msg_prefix_ << ")" << std::endl - << " File " << file_ << std::endl - << " Line " << line_ << std::endl; - - auto msg = ss.str(); - - return _strdup( msg.c_str() ); + return what_msg_.c_str(); } public: exchcxx_exception( std::string file, int line, std::string msg) : - file_(file), line_(line), msg_prefix_(msg) { } + file_(std::move(file)), line_(line), msg_prefix_(std::move(msg)) { + std::stringstream ss; + ss << "EXCHCXX Exception (" << msg_prefix_ << ")" << std::endl + << " File " << file_ << std::endl + << " Line " << line_ << std::endl; + what_msg_ = ss.str(); + } }; From 4a931c31ed7dfcd9070645cca0107ced7b74a6a2 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:38:16 +0200 Subject: [PATCH 09/39] comment cl warning suppression flags --- src/CMakeLists.txt | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a29cd88..a483906 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -47,22 +47,22 @@ if(MSVC) -Wno-unused-parameter -Wno-unused-variable ) - else() # cl - target_compile_options( exchcxx PUBLIC - /wd4003 # not enough actual parameters for macro 'identifier' - /wd4061 # enumerator 'enumerator' in switch of enum 'enumeration' is not explicitly handled by a case label - /wd4244 # conversion from 'type1' to 'type2', possible loss of data - /wd4266 # no override available for virtual member function from base 'class'; function is hidden - /wd4267 # conversion from 'size_t' to 'type', possible loss of data - /wd4365 # conversion from 'type1' to 'type2', signed/unsigned mismatch - /wd4514 # unreferenced inline function has been removed - /wd4267 # conversion from 'size_t' to 'type', possible loss of data - /wd4710 # function 'function' not inlined - /wd4711 # function 'function' selected for automatic inline expansion - /wd4800 # forcing value to bool 'true' or 'false' (performance warning) - /wd4820 # 'bytes' bytes padding added after construct 'member_name' - /wd5246 # C-style struct initialization may not be portable - ) + # else() # cl + # target_compile_options( exchcxx PUBLIC + # /wd4003 # not enough actual parameters for macro 'identifier' + # /wd4061 # enumerator 'enumerator' in switch of enum 'enumeration' is not explicitly handled by a case label + # /wd4244 # conversion from 'type1' to 'type2', possible loss of data + # /wd4266 # no override available for virtual member function from base 'class'; function is hidden + # /wd4267 # conversion from 'size_t' to 'type', possible loss of data + # /wd4365 # conversion from 'type1' to 'type2', signed/unsigned mismatch + # /wd4514 # unreferenced inline function has been removed + # /wd4267 # conversion from 'size_t' to 'type', possible loss of data + # /wd4710 # function 'function' not inlined + # /wd4711 # function 'function' selected for automatic inline expansion + # /wd4800 # forcing value to bool 'true' or 'false' (performance warning) + # /wd4820 # 'bytes' bytes padding added after construct 'member_name' + # /wd5246 # C-style struct initialization may not be portable + # ) endif() endif() if( EXCHCXX_ENABLE_LIBXC ) From 574602351aa176610d1f903ea8b320837e8a3c7e Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:43:43 +0200 Subject: [PATCH 10/39] fix(msvc): add /EHsc and /Zc:preprocessor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /EHsc enables the standard C++ exception-handling model, eliminating C4577 ('noexcept' used without exception handling mode specified). /Zc:preprocessor enables MSVC's conforming preprocessor (ISO C11/C17 behaviour), which correctly treats an empty macro argument as a valid single argument. This silences C4003 ('not enough arguments for function-like macro invocation') that arose wherever NOTYPE — defined as an empty token — was passed to TYPED_*_OPARAMS_*() macros in the FORWARD_XC_ARGS expansion chain. --- exchcxx-build-msvc.ps1 | 159 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 exchcxx-build-msvc.ps1 diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 new file mode 100644 index 0000000..adf9461 --- /dev/null +++ b/exchcxx-build-msvc.ps1 @@ -0,0 +1,159 @@ +# exchcxx-build-msvc.ps1 +# Build and test ExchCXX on Windows with MSVC native cl.exe. +# Run from the ExchCXX repo root in a PowerShell. +# +# Usage: +# .\exchcxx-build-msvc.ps1 # Full build + test +# .\exchcxx-build-msvc.ps1 -SkipConfigure # Incremental build (skip cmake configure) +# .\exchcxx-build-msvc.ps1 -SkipTests # Build only, no tests + +param( + [switch]$SkipConfigure, + [switch]$SkipTests +) + +$ErrorActionPreference = "Stop" +$RepoRoot = $PSScriptRoot +$BuildDir = "$RepoRoot\build-msvc" +$QdkRoot = "C:\Users\v-lercole\src\qdk-chemistry" +$VcpkgInstalledDir = "$QdkRoot\vcpkg_installed" +$VcpkgTriplet = "x64-windows-static-md" + +Write-Host "============================================" -ForegroundColor Cyan +Write-Host " ExchCXX - Windows Build (MSVC) " -ForegroundColor Cyan +Write-Host "============================================" -ForegroundColor Cyan +Write-Host "Repo root: $RepoRoot" +Write-Host "" + +function Assert-Command($Name) { + if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) { + Write-Error "$Name not found in PATH. Please install it first." + exit 1 + } +} + +# -------------------------------------------------------------------------- +# Set up MSVC environment +# -------------------------------------------------------------------------- +$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" +$vsPath = & $vswhere -latest -products * -property installationPath 2>$null + +# Set up MSVC developer environment (vcvarsall) +$vcvarsall = "$vsPath\VC\Auxiliary\Build\vcvarsall.bat" +if (Test-Path $vcvarsall) { + $tempFile = [System.IO.Path]::GetTempFileName() + cmd /c "`"$vcvarsall`" x64 && set > `"$tempFile`"" + Get-Content $tempFile | ForEach-Object { + if ($_ -match "^([^=]+)=(.*)$") { + [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2], "Process") + } + } + Remove-Item $tempFile +} + +# Set up vcpkg environment (reuse qdk-chemistry's vcpkg_installed) +$vcpkgRoot = $null +$vsVcpkg = "$vsPath\VC\vcpkg\vcpkg.exe" +if (Test-Path $vsVcpkg) { + $vcpkgRoot = Split-Path $vsVcpkg +} elseif ($env:VCPKG_INSTALLATION_ROOT -and (Test-Path "$($env:VCPKG_INSTALLATION_ROOT)\vcpkg.exe")) { + $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT +} else { + $vcpkgRoot = "$QdkRoot\vcpkg-tool" +} + +$toolchainFile = "$vcpkgRoot\scripts\buildsystems\vcpkg.cmake" +$env:CMAKE_TOOLCHAIN_FILE = $toolchainFile +$env:VCPKG_TARGET_TRIPLET = $VcpkgTriplet +$env:VCPKG_INSTALLED_DIR = $VcpkgInstalledDir +$env:CMAKE_PREFIX_PATH = "$VcpkgInstalledDir\$VcpkgTriplet" +$env:PATH = "$VcpkgInstalledDir\$VcpkgTriplet\bin;$VcpkgInstalledDir\$VcpkgTriplet\debug\bin;$env:PATH" + +# -------------------------------------------------------------------------- +# Verify environment +# -------------------------------------------------------------------------- +foreach ($cmd in @("cl", "cmake", "ninja")) { + Assert-Command $cmd +} + +if (-not $env:CMAKE_TOOLCHAIN_FILE) { + Write-Error "CMAKE_TOOLCHAIN_FILE not set. Run qdk-chemistry's test-windows-build-msvc.ps1 -SkipCpp -SkipPython first to set up the environment." + exit 1 +} + +Write-Host "=== Environment ===" -ForegroundColor Yellow +Write-Host " cl: $(Get-Command cl | Select-Object -ExpandProperty Source)" +Write-Host " cmake: $(Get-Command cmake | Select-Object -ExpandProperty Source)" +Write-Host " ninja: $(Get-Command ninja | Select-Object -ExpandProperty Source)" +Write-Host " TOOLCHAIN_FILE: $env:CMAKE_TOOLCHAIN_FILE" +Write-Host " VCPKG_INSTALLED: $VcpkgInstalledDir" +Write-Host "" + +# -------------------------------------------------------------------------- +# Configure +# -------------------------------------------------------------------------- + +if (-not $SkipConfigure) { + Write-Host "=== Configure ===" -ForegroundColor Yellow + + cmake -S "$RepoRoot" -B "$BuildDir" ` + -GNinja ` + -DCMAKE_POLICY_VERSION_MINIMUM="3.5" ` + -DFETCHCONTENT_QUIET=OFF ` + -DBUILD_SHARED_LIBS=OFF ` + -DCMAKE_BUILD_TYPE=Release ` + -DCMAKE_CXX_STANDARD=20 ` + -DCMAKE_CXX_STANDARD_REQUIRED=ON ` + -DCMAKE_C_COMPILER=cl ` + -DCMAKE_CXX_COMPILER=cl ` + -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` + -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` + -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` + -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` + -DVCPKG_INSTALLED_DIR="$VcpkgInstalledDir" ` + -DEXCHCXX_ENABLE_LIBXC=ON ` + -DEXCHCXX_ENABLE_CUDA=OFF ` + -DEXCHCXX_ENABLE_HIP=OFF ` + -DEXCHCXX_ENABLE_SYCL=OFF ` + -DEXCHCXX_ENABLE_TESTS=ON + if ($LASTEXITCODE -ne 0) { Write-Error "CMake configure failed"; exit 1 } + Write-Host "Configure succeeded." -ForegroundColor Green +} else { + Write-Host "=== Skipping configure (incremental build) ===" -ForegroundColor DarkGray + if (-not (Test-Path "$BuildDir\build.ninja")) { + Write-Error "No existing build found at $BuildDir. Run without -SkipConfigure first." + exit 1 + } +} + +# -------------------------------------------------------------------------- +# Build +# -------------------------------------------------------------------------- +Write-Host "" +Write-Host "=== Build ===" -ForegroundColor Yellow +cmake --build "$BuildDir" --parallel 6 2>&1 *> "$BuildDir\build.log" +if ($LASTEXITCODE -ne 0) { Write-Error "Build failed (see $BuildDir\build.log)"; exit 1 } +Write-Host "Build succeeded." -ForegroundColor Green + +# -------------------------------------------------------------------------- +# Test +# -------------------------------------------------------------------------- +if (-not $SkipTests) { + Write-Host "" + Write-Host "=== Test ===" -ForegroundColor Yellow + $env:OMP_NUM_THREADS = 4 + Push-Location "$BuildDir" + ctest --output-on-failure --verbose + $ctestExit = $LASTEXITCODE + Pop-Location + if ($ctestExit -ne 0) { + Write-Warning "Some tests failed (exit code: $ctestExit)" + } else { + Write-Host "All tests passed." -ForegroundColor Green + } +} + +Write-Host "" +Write-Host "============================================" -ForegroundColor Cyan +Write-Host " Done! " -ForegroundColor Cyan +Write-Host "============================================" -ForegroundColor Cyan From 2e9de304de0438805c005b6537b3d55428a42fdd Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:44:06 +0200 Subject: [PATCH 11/39] =?UTF-8?q?suppress(msvc):=20C4800=20=E2=80=94=20imp?= =?UTF-8?q?licit=20double-to-bool=20in=20generated=20kernel=20headers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ~44 000 C4800 occurrences are all in auto-generated XC kernel implementation headers under include/exchcxx/impl/builtin/kernels/. These files are produced by a code-generation script and are not hand-maintained; patching them individually is not sustainable. The conversion is intentional (the generated code encodes boolean screening conditions as doubles that happen to carry 0.0/non-zero values), so the warning carries no actionable signal here. --- exchcxx-build-msvc.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 index adf9461..3e04878 100644 --- a/exchcxx-build-msvc.ps1 +++ b/exchcxx-build-msvc.ps1 @@ -106,7 +106,7 @@ if (-not $SkipConfigure) { -DCMAKE_CXX_STANDARD_REQUIRED=ON ` -DCMAKE_C_COMPILER=cl ` -DCMAKE_CXX_COMPILER=cl ` - -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` + -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` From 1243e1b82de0599609139e8e520640379237a2c6 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:44:31 +0200 Subject: [PATCH 12/39] =?UTF-8?q?suppress(msvc):=20C4514=20=E2=80=94=20unr?= =?UTF-8?q?eferenced=20inline=20functions=20removed=20by=20linker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C4514 fires when the compiler removes an inline function that was never called in a translation unit. The warning is purely informational (level 4, off by default): the linker dead-strips these symbols correctly and there is no correctness risk. In ExchCXX the 1 097 occurrences come from the XcKernel helper overloads in xc_kernel.hpp that are specialised per kernel type but not needed in every TU. --- exchcxx-build-msvc.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 index 3e04878..6f32528 100644 --- a/exchcxx-build-msvc.ps1 +++ b/exchcxx-build-msvc.ps1 @@ -106,7 +106,7 @@ if (-not $SkipConfigure) { -DCMAKE_CXX_STANDARD_REQUIRED=ON ` -DCMAKE_C_COMPILER=cl ` -DCMAKE_CXX_COMPILER=cl ` - -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` + -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` From 106c044b7f45669c078719080a46c03fd0d50b9a Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:44:44 +0200 Subject: [PATCH 13/39] =?UTF-8?q?suppress(msvc):=20C4710/C4711=20=E2=80=94?= =?UTF-8?q?=20function=20inlining=20diagnostics?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C4710 ('function not inlined') and C4711 ('function selected for automatic inline expansion') are level-4 informational diagnostics that report the compiler's inlining decisions. They carry no correctness signal; whether a function gets inlined is a QoI choice left to the optimizer. The ~1 400 combined occurrences all originate from STL string/exception machinery pulled in by exchcxx_exception.hpp and screening_interface.hpp. --- exchcxx-build-msvc.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 index 6f32528..9ebcc53 100644 --- a/exchcxx-build-msvc.ps1 +++ b/exchcxx-build-msvc.ps1 @@ -106,7 +106,7 @@ if (-not $SkipConfigure) { -DCMAKE_CXX_STANDARD_REQUIRED=ON ` -DCMAKE_C_COMPILER=cl ` -DCMAKE_CXX_COMPILER=cl ` - -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` + -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` From 74d17d0c92fcac98853ad4effaf9f2842a10e6d4 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:44:58 +0200 Subject: [PATCH 14/39] =?UTF-8?q?suppress(msvc):=20C4061=20=E2=80=94=20enu?= =?UTF-8?q?merator=20not=20handled=20by=20explicit=20switch=20case?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C4061 fires for every Kernel enumerator that falls through to a default: label in kernels.hpp. The switch is intentionally written with a catch-all default that throws an exception for unrecognised kernels; every new enumerator is handled uniformly by that path. Requiring an explicit case for each of the 100+ kernel variants would make the switch unmaintainable without adding safety. --- exchcxx-build-msvc.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 index 9ebcc53..595472c 100644 --- a/exchcxx-build-msvc.ps1 +++ b/exchcxx-build-msvc.ps1 @@ -106,7 +106,7 @@ if (-not $SkipConfigure) { -DCMAKE_CXX_STANDARD_REQUIRED=ON ` -DCMAKE_C_COMPILER=cl ` -DCMAKE_CXX_COMPILER=cl ` - -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` + -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` From 4cfce2a6cc7ce9e9db62b847186865b068cba8c2 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:45:13 +0200 Subject: [PATCH 15/39] =?UTF-8?q?suppress(msvc):=20C4266=20=E2=80=94=20vir?= =?UTF-8?q?tual=20function=20with=20no=20override=20available?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C4266 fires on BuiltinKernelImpl because the base class BuiltinKernel declares pure-virtual eval_exc/eval_fxc/... overloads for all three approximation types (LDA, GGA, MGGA) and each specialisation only overrides its own subset, intentionally inheriting the base not-implemented default for the other types. MSVC treats the unoverridden virtuals as a warning even though that design is correct. --- exchcxx-build-msvc.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 index 595472c..42ecc2e 100644 --- a/exchcxx-build-msvc.ps1 +++ b/exchcxx-build-msvc.ps1 @@ -106,7 +106,7 @@ if (-not $SkipConfigure) { -DCMAKE_CXX_STANDARD_REQUIRED=ON ` -DCMAKE_C_COMPILER=cl ` -DCMAKE_CXX_COMPILER=cl ` - -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` + -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /wd4266 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` From 5fd0d51d1abf83d8afa5aa68ff84e46fb69358c3 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:45:29 +0200 Subject: [PATCH 16/39] =?UTF-8?q?suppress(msvc):=20C4702=20=E2=80=94=20unr?= =?UTF-8?q?eachable=20code=20in=20kernel=20dispatch=20tables?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 160 C4702 occurrences are in builtin_kernel.cxx in the large kernel-name-to-type dispatch switch. After each case the function returns; MSVC considers any following statement unreachable. These are artefacts of macro-expanded dispatch tables where the compiler loses track of control flow, not real dead code. Suppressing avoids noise without hiding genuine unreachable-code bugs elsewhere (none present). --- exchcxx-build-msvc.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 index 42ecc2e..ece8694 100644 --- a/exchcxx-build-msvc.ps1 +++ b/exchcxx-build-msvc.ps1 @@ -106,7 +106,7 @@ if (-not $SkipConfigure) { -DCMAKE_CXX_STANDARD_REQUIRED=ON ` -DCMAKE_C_COMPILER=cl ` -DCMAKE_CXX_COMPILER=cl ` - -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /wd4266 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` + -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /wd4266 /wd4702 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` From e7110fe34f7a33e70fbfb49be7d3b4679439b9ab Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:45:42 +0200 Subject: [PATCH 17/39] =?UTF-8?q?suppress(msvc):=20C4365=20=E2=80=94=20sig?= =?UTF-8?q?ned/unsigned=20mismatch=20in=20STL-heavy=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 60 C4365 occurrences are in xc_functional.cxx and libxc.cxx where int loop indices are compared against or passed to STL container methods that take size_type (size_t). C4365 is a level-4 diagnostic not in the mandatory warning list. The mismatches do not represent real bugs: the loop bounds are always non-negative and well within size_t range. Fixing them would require pervasive signed/unsigned casts that reduce readability for no safety gain. --- exchcxx-build-msvc.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 index ece8694..a5bfe1a 100644 --- a/exchcxx-build-msvc.ps1 +++ b/exchcxx-build-msvc.ps1 @@ -106,7 +106,7 @@ if (-not $SkipConfigure) { -DCMAKE_CXX_STANDARD_REQUIRED=ON ` -DCMAKE_C_COMPILER=cl ` -DCMAKE_CXX_COMPILER=cl ` - -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /wd4266 /wd4702 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` + -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /wd4266 /wd4702 /wd4365 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` From 87163daf4c989d5041bc81e3ffb02bd1d652c7b8 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:45:55 +0200 Subject: [PATCH 18/39] =?UTF-8?q?suppress(msvc):=20C5045=20=E2=80=94=20Spe?= =?UTF-8?q?ctre=20mitigation=20informational?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C5045 is an informational remark (not a true warning) telling the user that the compiler would insert a Spectre v1 load fence if /Qspectre were passed. ExchCXX is a numerical library, not security-sensitive code, and /Qspectre is not enabled in this build. The remark adds no actionable information. --- exchcxx-build-msvc.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 index a5bfe1a..fef0d8d 100644 --- a/exchcxx-build-msvc.ps1 +++ b/exchcxx-build-msvc.ps1 @@ -106,7 +106,7 @@ if (-not $SkipConfigure) { -DCMAKE_CXX_STANDARD_REQUIRED=ON ` -DCMAKE_C_COMPILER=cl ` -DCMAKE_CXX_COMPILER=cl ` - -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /wd4266 /wd4702 /wd4365 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` + -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /wd4266 /wd4702 /wd4365 /wd5045 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` From 0f179ab5606af9a617dc0dfe2b895660dad878ba Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:46:11 +0200 Subject: [PATCH 19/39] =?UTF-8?q?suppress(msvc):=20C4820/C4626=20=E2=80=94?= =?UTF-8?q?=20struct=20padding=20and=20deleted=20assignment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C4820 ('bytes of padding added after data member') is a level-4 diagnostic about ABI layout decisions made by the compiler; callers cannot rely on internal struct layout. C4626 ('assignment operator was implicitly defined as deleted') fires because BuiltinKernelInterface and LibxcKernelInterface hold reference members, making copy-assignment impossible by design. The classes are intended to be non-copyable; the deleted operator is correct behaviour. Both are purely informational and not in the mandatory warning list. --- exchcxx-build-msvc.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 index fef0d8d..2d702d5 100644 --- a/exchcxx-build-msvc.ps1 +++ b/exchcxx-build-msvc.ps1 @@ -106,7 +106,7 @@ if (-not $SkipConfigure) { -DCMAKE_CXX_STANDARD_REQUIRED=ON ` -DCMAKE_C_COMPILER=cl ` -DCMAKE_CXX_COMPILER=cl ` - -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /wd4266 /wd4702 /wd4365 /wd5045 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` + -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /wd4266 /wd4702 /wd4365 /wd5045 /wd4820 /wd4626 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` From ff42cd11c0d3cbf1d212ee7aad963d0180ffb322 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:47:14 +0200 Subject: [PATCH 20/39] =?UTF-8?q?fix(msvc):=20C4100/C4101=20=E2=80=94=20un?= =?UTF-8?q?used=20tau=20params=20and=20vtau=5Fk=20in=20deorbitalized.hpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Deorbitalized the deorbitalization substitutes tau with ke_traits::eval_*_unpolar/polar called with tau=0.0, so the incoming tau/tau_a/tau_b parameters from the MGGA interface are never read. Mark them [[maybe_unused]] to satisfy C4100. vtau_k was declared alongside the other kinetic-energy VXC outputs but all tau outputs were already captured through the dummy variable in the ke_traits calls; vtau_k was never written to or read. Remove it to fix C4101 (local variable initialized but not referenced). --- include/exchcxx/impl/builtin/kernels/deorbitalized.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/exchcxx/impl/builtin/kernels/deorbitalized.hpp b/include/exchcxx/impl/builtin/kernels/deorbitalized.hpp index e31a41e..e34c74d 100644 --- a/include/exchcxx/impl/builtin/kernels/deorbitalized.hpp +++ b/include/exchcxx/impl/builtin/kernels/deorbitalized.hpp @@ -72,7 +72,7 @@ struct kernel_traits> { static constexpr bool is_epc = false; BUILTIN_KERNEL_EVAL_RETURN - eval_exc_unpolar( double rho, double sigma, double lapl, double tau, double& eps ) { + eval_exc_unpolar( double rho, double sigma, double lapl, [[maybe_unused]] double tau, double& eps ) { double TAU; ke_traits::eval_exc_unpolar(rho, sigma, lapl, 0.0, TAU); @@ -83,7 +83,7 @@ struct kernel_traits> { } BUILTIN_KERNEL_EVAL_RETURN - eval_exc_vxc_unpolar( double rho, double sigma, double lapl, double tau, double& eps, double& vrho, double& vsigma, double& vlapl, double& vtau ) { + eval_exc_vxc_unpolar( double rho, double sigma, double lapl, [[maybe_unused]] double tau, double& eps, double& vrho, double& vsigma, double& vlapl, double& vtau ) { double TAU, vrho_k, vsigma_k, vlapl_k, dummy; ke_traits::eval_exc_vxc_unpolar(rho, sigma, lapl, 0.0, TAU, vrho_k, vsigma_k, vlapl_k, dummy); @@ -100,7 +100,7 @@ struct kernel_traits> { } BUILTIN_KERNEL_EVAL_RETURN - eval_exc_polar( double rho_a, double rho_b, double sigma_aa, double sigma_ab, double sigma_bb, double lapl_a, double lapl_b, double tau_a, double tau_b, double& eps ) { + eval_exc_polar( double rho_a, double rho_b, double sigma_aa, double sigma_ab, double sigma_bb, double lapl_a, double lapl_b, [[maybe_unused]] double tau_a, [[maybe_unused]] double tau_b, double& eps ) { double TAU_A, TAU_B; ke_traits::eval_exc_polar(rho_a, 0.0, sigma_aa, 0.0, 0.0, lapl_a, 0.0, 0.0, 0.0, TAU_A); @@ -113,9 +113,9 @@ struct kernel_traits> { } BUILTIN_KERNEL_EVAL_RETURN - eval_exc_vxc_polar( double rho_a, double rho_b, double sigma_aa, double sigma_ab, double sigma_bb, double lapl_a, double lapl_b, double tau_a, double tau_b, double& eps, double& vrho_a, double& vrho_b, double& vsigma_aa, double& vsigma_ab, double& vsigma_bb, double& vlapl_a, double& vlapl_b, double& vtau_a, double& vtau_b ) { + eval_exc_vxc_polar( double rho_a, double rho_b, double sigma_aa, double sigma_ab, double sigma_bb, double lapl_a, double lapl_b, [[maybe_unused]] double tau_a, [[maybe_unused]] double tau_b, double& eps, double& vrho_a, double& vrho_b, double& vsigma_aa, double& vsigma_ab, double& vsigma_bb, double& vlapl_a, double& vlapl_b, double& vtau_a, double& vtau_b ) { - double TAU_A, TAU_B, vrho_a_k, vrho_b_k, vsigma_aa_k, vsigma_bb_k, vlapl_a_k, vlapl_b_k, vtau_k, dummy; + double TAU_A, TAU_B, vrho_a_k, vrho_b_k, vsigma_aa_k, vsigma_bb_k, vlapl_a_k, vlapl_b_k, dummy; ke_traits::eval_exc_vxc_polar(rho_a, 0.0, sigma_aa, 0.0, 0.0, lapl_a, 0.0, 0.0, 0.0, TAU_A, vrho_a_k, dummy, vsigma_aa_k, dummy, dummy, vlapl_a_k, dummy, dummy, dummy); ke_traits::eval_exc_vxc_polar(rho_b, 0.0, sigma_bb, 0.0, 0.0, lapl_b, 0.0, 0.0, 0.0, TAU_B, vrho_b_k, dummy, vsigma_bb_k, dummy, dummy, vlapl_b_k, dummy, dummy, dummy); From 163be0ec6ca907a00d254e0455c49528131195ea Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:51:54 +0200 Subject: [PATCH 21/39] =?UTF-8?q?fix(msvc):=20C4267=20=E2=80=94=20size=5Ft?= =?UTF-8?q?=E2=86=92int=20conversions=20in=20test=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The buffer_len() helpers on XCKernelImpl return size_t; storing the results in int locals caused C4267 ('conversion from size_t to int, possible loss of data'). Changed the len_* variables in xc_kernel_test.cxx to size_t, which also matches the vector<> size_type they are used with. In reference_values.cxx the load_reference_*() helpers declare int npts and assign from std::vector::size() (size_t). Added explicit static_cast at each assignment; npts stays int because the functions return std::pair and the values are always small enough to fit. In xc_functional_test.cxx npts was declared size_t but passed directly to eval_exc_vxc() whose first parameter is int N; changed to int. These changes also remove the C4267 cascade into xc_kernel.hpp's template forwarding wrappers, which fired because those templates were instantiated with size_t as the N argument. --- test/reference_values.cxx | 28 ++++++++++++++-------------- test/xc_functional_test.cxx | 2 +- test/xc_kernel_test.cxx | 30 +++++++++++++++--------------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/test/reference_values.cxx b/test/reference_values.cxx index dac4d7c..5590175 100644 --- a/test/reference_values.cxx +++ b/test/reference_values.cxx @@ -292,7 +292,7 @@ lda_reference load_lda_reference_values(ExchCXX::Kernel k, ExchCXX::Spin p) { if( p == Spin::Unpolarized ) { copy_iterable( rho, std::back_inserter(ref_vals.rho) ); - ref_vals.npts = rho.size(); + ref_vals.npts = static_cast(rho.size()); switch(k) { case Kernel::SlaterExchange: @@ -306,7 +306,7 @@ lda_reference load_lda_reference_values(ExchCXX::Kernel k, ExchCXX::Spin p) { } else { copy_iterable( rho_polarized, std::back_inserter(ref_vals.rho) ); - ref_vals.npts = rho_polarized.size() / 2; + ref_vals.npts = static_cast(rho_polarized.size() / 2); switch(k) { case Kernel::SlaterExchange: @@ -333,7 +333,7 @@ gga_reference load_gga_reference_values(ExchCXX::Kernel k, ExchCXX::Spin p) { if( p == Spin::Unpolarized ) { - ref_vals.npts = rho.size(); + ref_vals.npts = static_cast(rho.size()); copy_iterable( rho, std::back_inserter(ref_vals.rho) ); copy_iterable( sigma, std::back_inserter(ref_vals.sigma) ); @@ -349,7 +349,7 @@ gga_reference load_gga_reference_values(ExchCXX::Kernel k, ExchCXX::Spin p) { } else { - ref_vals.npts = rho_polarized.size() / 2; + ref_vals.npts = static_cast(rho_polarized.size() / 2); copy_iterable( rho_polarized, std::back_inserter(ref_vals.rho) ); copy_iterable( sigma_polarized, std::back_inserter(ref_vals.sigma) ); @@ -380,7 +380,7 @@ mgga_reference load_mgga_reference_values(ExchCXX::Kernel k, ExchCXX::Spin p, bo copy_iterable( sigma, std::back_inserter(ref_vals.sigma) ); copy_iterable( tau, std::back_inserter(ref_vals.tau) ); if(need_lap) copy_iterable( lapl, std::back_inserter(ref_vals.lapl) ); - ref_vals.npts = rho.size(); + ref_vals.npts = static_cast(rho.size()); switch(k) { case Kernel::SCAN_X: @@ -406,7 +406,7 @@ mgga_reference load_mgga_reference_values(ExchCXX::Kernel k, ExchCXX::Spin p, bo copy_iterable( sigma_polarized, std::back_inserter(ref_vals.sigma) ); copy_iterable( tau_polarized, std::back_inserter(ref_vals.tau) ); if(need_lap) copy_iterable( lapl_polarized, std::back_inserter(ref_vals.lapl) ); - ref_vals.npts = rho_polarized.size() / 2; + ref_vals.npts = static_cast(rho_polarized.size() / 2); switch(k) { case Kernel::SCAN_X: @@ -544,10 +544,10 @@ std::pair> load_reference_density(ExchCXX::Spin s) { int npts; if( s == ExchCXX::Spin::Polarized ) { - npts = rho_polarized.size() / 2; + npts = static_cast(rho_polarized.size() / 2); copy_iterable( rho_polarized, std::back_inserter(ref_rho) ); } else { - npts = rho.size(); + npts = static_cast(rho.size()); copy_iterable( rho, std::back_inserter(ref_rho) ); } return std::make_pair(npts, ref_rho); @@ -561,10 +561,10 @@ std::pair> load_reference_sigma(ExchCXX::Spin s) { int npts; if( s == ExchCXX::Spin::Polarized ) { - npts = sigma_polarized.size() / 3; + npts = static_cast(sigma_polarized.size() / 3); copy_iterable( sigma_polarized, std::back_inserter(ref_sigma) ); } else { - npts = sigma.size(); + npts = static_cast(sigma.size()); copy_iterable( sigma, std::back_inserter(ref_sigma) ); } return std::make_pair(npts, ref_sigma); @@ -577,10 +577,10 @@ std::pair> load_reference_lapl(ExchCXX::Spin s) { int npts; if( s == ExchCXX::Spin::Polarized ) { - npts = lapl_polarized.size() / 2; + npts = static_cast(lapl_polarized.size() / 2); copy_iterable( lapl_polarized, std::back_inserter(ref_lapl) ); } else { - npts = lapl.size(); + npts = static_cast(lapl.size()); copy_iterable( lapl, std::back_inserter(ref_lapl) ); } return std::make_pair(npts, ref_lapl); @@ -593,10 +593,10 @@ std::pair> load_reference_tau(ExchCXX::Spin s) { int npts; if( s == ExchCXX::Spin::Polarized ) { - npts = tau_polarized.size() / 2; + npts = static_cast(tau_polarized.size() / 2); copy_iterable( tau_polarized, std::back_inserter(ref_tau) ); } else { - npts = tau.size(); + npts = static_cast(tau.size()); copy_iterable( tau, std::back_inserter(ref_tau) ); } return std::make_pair(npts, ref_tau); diff --git a/test/xc_functional_test.cxx b/test/xc_functional_test.cxx index 58b0e9f..3bdc795 100644 --- a/test/xc_functional_test.cxx +++ b/test/xc_functional_test.cxx @@ -306,7 +306,7 @@ void check_correctness( TestInterface interface, Backend backend, Spin polar, [&](const auto& a){ coeffs.emplace_back( a.first ); } ); - size_t npts = 1024; + int npts = 1024; std::vector rho( func.rho_buffer_len(npts) ), diff --git a/test/xc_kernel_test.cxx b/test/xc_kernel_test.cxx index 71a099c..ab49131 100644 --- a/test/xc_kernel_test.cxx +++ b/test/xc_kernel_test.cxx @@ -980,21 +980,21 @@ void compare_libxc_builtin( TestInterface interface, EvalType evaltype, XCKernel func_builtin( Backend::builtin, kern, polar ); - const int len_rho = func_libxc.rho_buffer_len( npts ); - const int len_sigma = func_libxc.sigma_buffer_len( npts ); - const int len_lapl = func_libxc.lapl_buffer_len( npts ); - const int len_tau = func_libxc.tau_buffer_len( npts ); - - const int len_v2rho2 = func_libxc.v2rho2_buffer_len( npts ); - const int len_v2rhosigma = func_libxc.v2rhosigma_buffer_len( npts ); - const int len_v2rholapl = func_libxc.v2rholapl_buffer_len( npts ); - const int len_v2rhotau = func_libxc.v2rhotau_buffer_len( npts ); - const int len_v2sigma2 = func_libxc.v2sigma2_buffer_len( npts ); - const int len_v2sigmalapl = func_libxc.v2sigmalapl_buffer_len( npts ); - const int len_v2sigmatau = func_libxc.v2sigmatau_buffer_len( npts ); - const int len_v2lapl2 = func_libxc.v2lapl2_buffer_len( npts ); - const int len_v2lapltau = func_libxc.v2lapltau_buffer_len( npts ); - const int len_v2tau2 = func_libxc.v2tau2_buffer_len( npts ); + const size_t len_rho = func_libxc.rho_buffer_len( npts ); + const size_t len_sigma = func_libxc.sigma_buffer_len( npts ); + const size_t len_lapl = func_libxc.lapl_buffer_len( npts ); + const size_t len_tau = func_libxc.tau_buffer_len( npts ); + + const size_t len_v2rho2 = func_libxc.v2rho2_buffer_len( npts ); + const size_t len_v2rhosigma = func_libxc.v2rhosigma_buffer_len( npts ); + const size_t len_v2rholapl = func_libxc.v2rholapl_buffer_len( npts ); + const size_t len_v2rhotau = func_libxc.v2rhotau_buffer_len( npts ); + const size_t len_v2sigma2 = func_libxc.v2sigma2_buffer_len( npts ); + const size_t len_v2sigmalapl = func_libxc.v2sigmalapl_buffer_len( npts ); + const size_t len_v2sigmatau = func_libxc.v2sigmatau_buffer_len( npts ); + const size_t len_v2lapl2 = func_libxc.v2lapl2_buffer_len( npts ); + const size_t len_v2lapltau = func_libxc.v2lapltau_buffer_len( npts ); + const size_t len_v2tau2 = func_libxc.v2tau2_buffer_len( npts ); std::vector rho_small(len_rho, 1e-13); std::vector sigma_small(len_sigma, 1e-14); From 38285fccc3c9f2b7cfba41cb57229a83a6b0f62f Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:52:36 +0200 Subject: [PATCH 22/39] fix(msvc): C4018/C4701 in xc_kernel_test.cxx C4018 ('signed/unsigned mismatch'): the for-loop upper bounds were the len_* buffer-length variables, which were previously int; comparing them against the unsigned loop index (0ul) triggered C4018. The previous commit already changed those variables to size_t, so no loop-body changes are needed here. C4701 ('potentially uninitialized variable'): 'backend' was declared without an initializer and only set inside nested Catch2 SECTION blocks. MSVC cannot prove it is always assigned before use because the SECTION macro expands to control-flow that is opaque to the analyser. Giving 'backend' a default value of Backend::builtin at its declaration satisfies C4701 without changing observable test behaviour (each SECTION that cares overrides it explicitly). --- test/xc_kernel_test.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/xc_kernel_test.cxx b/test/xc_kernel_test.cxx index ab49131..143b489 100644 --- a/test/xc_kernel_test.cxx +++ b/test/xc_kernel_test.cxx @@ -65,7 +65,7 @@ TEST_CASE( "XCKernel Metadata Validity", "[xc-kernel]" ) { auto mgga_lapl_kernel_test = Kernel::R2SCANL_C; auto epc_lda_kernel_test = Kernel::EPC17_2; - Backend backend; + Backend backend = Backend::builtin; SECTION( "Pure LDA Unpolarized" ) { @@ -392,7 +392,7 @@ TEST_CASE( "XCKernel Metadata Validity", "[xc-kernel]" ) { TEST_CASE( "XCKernel Metadata Correctness", "[xc-kernel]" ) { - Backend backend; + Backend backend = Backend::builtin; SECTION( "LDA Kernels" ) { SECTION( "Libxc Backend" ) { backend = Backend::libxc; } From 46ba6010ce511bd551b78cba95522695ad4164dc Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 16:53:10 +0200 Subject: [PATCH 23/39] =?UTF-8?q?fix(msvc):=20C4189=20=E2=80=94=20xcNumber?= =?UTF-8?q?=20unused=20when=20XC=5FMAJOR=5FVERSION=20<=3D=207?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xcNumber was declared before a #if XC_MAJOR_VERSION > 7 block that was the only place it was referenced. When building against libxc 7 or earlier the variable is initialised but never read, triggering C4189 ('local variable is initialized but not referenced'). Move the declaration inside the #if guard and change the spanning return-expression pattern to explicit return statements on each branch, which also makes the preprocessor intent clearer. --- src/libxc.cxx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libxc.cxx b/src/libxc.cxx index 8d6b9e6..79efd6b 100644 --- a/src/libxc.cxx +++ b/src/libxc.cxx @@ -291,12 +291,11 @@ bool LibxcKernelImpl::is_polarized_() const noexcept { } bool LibxcKernelImpl::is_epc_() const noexcept { - int xcNumber = xc_info()->number; - return #if XC_MAJOR_VERSION > 7 - xcNumber == XC_LDA_C_EPC17 || xcNumber == XC_LDA_C_EPC17_2 || xcNumber == XC_LDA_C_EPC18_1 || xcNumber == XC_LDA_C_EPC18_2; + int xcNumber = xc_info()->number; + return xcNumber == XC_LDA_C_EPC17 || xcNumber == XC_LDA_C_EPC17_2 || xcNumber == XC_LDA_C_EPC18_1 || xcNumber == XC_LDA_C_EPC18_2; #else - false; + return false; #endif } From a63ab7ebef804e3c8b61f9b01667deac2fac40d6 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 17:05:39 +0200 Subject: [PATCH 24/39] =?UTF-8?q?fix(msvc/gcc):=20C4267=20in=20xc=5Ffuncti?= =?UTF-8?q?onal=5Ftest.cxx=20=E2=80=94=20keep=20size=5Ft,=20cast=20at=20ev?= =?UTF-8?q?al=20site?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous fix changed npts from size_t to int, which was correct for MSVC but introduced an implicit int→size_t conversion at the buffer_len call sites that GCC/Clang would warn about with -Wsign-conversion. Better approach: keep npts as size_t (correct type for buffer lengths) and add static_cast only at the eval_exc_vxc call sites where int N is required. No conversion warnings on any compiler. --- test/xc_functional_test.cxx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/xc_functional_test.cxx b/test/xc_functional_test.cxx index 3bdc795..fc9f7e9 100644 --- a/test/xc_functional_test.cxx +++ b/test/xc_functional_test.cxx @@ -306,7 +306,7 @@ void check_correctness( TestInterface interface, Backend backend, Spin polar, [&](const auto& a){ coeffs.emplace_back( a.first ); } ); - int npts = 1024; + size_t npts = 1024; std::vector rho( func.rho_buffer_len(npts) ), @@ -382,13 +382,13 @@ void check_correctness( TestInterface interface, Backend backend, Spin polar, vtau( func.vtau_buffer_len( npts ) ); if( func.is_lda() ) - func.eval_exc_vxc( npts, rho.data(), eps.data(), vrho.data() ); + func.eval_exc_vxc( static_cast(npts), rho.data(), eps.data(), vrho.data() ); else if( func.is_gga() ) - func.eval_exc_vxc( npts, rho.data(), sigma.data(), + func.eval_exc_vxc( static_cast(npts), rho.data(), sigma.data(), eps.data(), vrho.data(), vsigma.data() ); else if( func.is_mgga() ) - func.eval_exc_vxc( npts, rho.data(), sigma.data(), - lapl.data(), tau.data(), eps.data(), vrho.data(), + func.eval_exc_vxc( static_cast(npts), rho.data(), sigma.data(), + lapl.data(), tau.data(), eps.data(), vrho.data(), vsigma.data(), vlapl.data(), vtau.data() ); From 853780f701f2cb9f83159843eff7a49910a978a8 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 17:06:37 +0200 Subject: [PATCH 25/39] refactor(msvc): move warning-suppression flags from build script to CMakeLists.txt The /EHsc, /Zc:preprocessor and /wd* flags were sitting in the PowerShell build helper, which means they were silently absent for any cmake invocation that didn't go through that script (CI, IDEs, sub- project builds, etc.). Move them into the existing if(MSVC) / else() # cl block in src/CMakeLists.txt so they are part of the project's build definition and applied unconditionally whenever cl.exe is the compiler. The commented-out placeholder block that was already there is now replaced with the actual flags plus a rationale comment for each suppression. The build script retains only /W3 and the mandatory /w1XXXX enable flags, which are intentionally kept there as build-policy enforcement rather than project defaults. Note: most /wd* flags are level-4 warnings that become visible under /W3 because MSVC's STL headers internally push the warning level to 4 via #pragma warning(push, 4), causing user template instantiations inside those headers to inherit the elevated level. --- exchcxx-build-msvc.ps1 | 2 +- src/CMakeLists.txt | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 index 2d702d5..0e61e4b 100644 --- a/exchcxx-build-msvc.ps1 +++ b/exchcxx-build-msvc.ps1 @@ -106,7 +106,7 @@ if (-not $SkipConfigure) { -DCMAKE_CXX_STANDARD_REQUIRED=ON ` -DCMAKE_C_COMPILER=cl ` -DCMAKE_CXX_COMPILER=cl ` - -DCMAKE_CXX_FLAGS="/W3 /EHsc /Zc:preprocessor /wd4800 /wd4514 /wd4710 /wd4711 /wd4061 /wd4266 /wd4702 /wd4365 /wd5045 /wd4820 /wd4626 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` + -DCMAKE_CXX_FLAGS="/W3 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a483906..464a5f6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -47,22 +47,22 @@ if(MSVC) -Wno-unused-parameter -Wno-unused-variable ) - # else() # cl - # target_compile_options( exchcxx PUBLIC - # /wd4003 # not enough actual parameters for macro 'identifier' - # /wd4061 # enumerator 'enumerator' in switch of enum 'enumeration' is not explicitly handled by a case label - # /wd4244 # conversion from 'type1' to 'type2', possible loss of data - # /wd4266 # no override available for virtual member function from base 'class'; function is hidden - # /wd4267 # conversion from 'size_t' to 'type', possible loss of data - # /wd4365 # conversion from 'type1' to 'type2', signed/unsigned mismatch - # /wd4514 # unreferenced inline function has been removed - # /wd4267 # conversion from 'size_t' to 'type', possible loss of data - # /wd4710 # function 'function' not inlined - # /wd4711 # function 'function' selected for automatic inline expansion - # /wd4800 # forcing value to bool 'true' or 'false' (performance warning) - # /wd4820 # 'bytes' bytes padding added after construct 'member_name' - # /wd5246 # C-style struct initialization may not be portable - # ) + else() # cl + target_compile_options( exchcxx PUBLIC + /EHsc # enable standard C++ exception-handling model (fixes C4577) + /Zc:preprocessor # conforming preprocessor: empty macro args are valid (fixes C4003 via NOTYPE) + /wd4800 # implicit double-to-bool: fires in auto-generated kernel headers, intentional + /wd4514 # unreferenced inline removed: informational, level 4, linker dead-strips correctly + /wd4710 # function not inlined: informational, level 4, optimizer decision + /wd4711 # function auto-inlined: informational, level 4, optimizer decision + /wd4061 # enumerator not in switch case: intentional default: handler covers all kernels + /wd4266 # no override for virtual function: by-design partial override in APPROX specialisations + /wd4702 # unreachable code: macro-expanded dispatch tables, not real dead code + /wd4365 # signed/unsigned in STL code: safe, values always non-negative + /wd5045 # Spectre mitigation remark: informational, /Qspectre not in use + /wd4820 # struct padding: ABI layout decision, informational + /wd4626 # assignment operator deleted: by-design non-copyable classes with reference members + ) endif() endif() if( EXCHCXX_ENABLE_LIBXC ) From f526b7a1b6d532dc8e2c12823d1f148b5dbde512 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 18:09:22 +0200 Subject: [PATCH 26/39] =?UTF-8?q?fix(msvc):=20C4267=20=E2=80=94=20remainin?= =?UTF-8?q?g=20size=5Ft=E2=86=92int=20casts=20in=20kern.eval=5F*=20and=20c?= =?UTF-8?q?ompare=5Flibxc=5Fbuiltin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kern.eval_exc / kern.eval_exc_vxc calls in xc_functional_test.cxx were missed in the previous C4267 pass (only func.eval_exc_vxc was fixed). Also cast npts_lda→int at its initialisation site in xc_kernel_test.cxx. --- test/xc_functional_test.cxx | 14 +++++++------- test/xc_kernel_test.cxx | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/xc_functional_test.cxx b/test/xc_functional_test.cxx index fc9f7e9..72a58da 100644 --- a/test/xc_functional_test.cxx +++ b/test/xc_functional_test.cxx @@ -345,26 +345,26 @@ void check_correctness( TestInterface interface, Backend backend, Spin polar, if( interface == TestInterface::EXC ) { if( kern.is_lda() ) - kern.eval_exc( npts, rho.data(), eps_refs.back().data() ); + kern.eval_exc( static_cast(npts), rho.data(), eps_refs.back().data() ); else if( kern.is_gga() ) - kern.eval_exc( npts, rho.data(), sigma.data(), + kern.eval_exc( static_cast(npts), rho.data(), sigma.data(), eps_refs.back().data() ); else if( kern.is_mgga() ) - kern.eval_exc( npts, rho.data(), sigma.data(), lapl.data(), tau.data(), + kern.eval_exc( static_cast(npts), rho.data(), sigma.data(), lapl.data(), tau.data(), eps_refs.back().data() ); } else if( interface == TestInterface::EXC_VXC ) { if( kern.is_lda() ) - kern.eval_exc_vxc( npts, rho.data(), eps_refs.back().data(), + kern.eval_exc_vxc( static_cast(npts), rho.data(), eps_refs.back().data(), vrho_refs.back().data() ); else if( kern.is_gga() ) - kern.eval_exc_vxc( npts, rho.data(), sigma.data(), + kern.eval_exc_vxc( static_cast(npts), rho.data(), sigma.data(), eps_refs.back().data(), vrho_refs.back().data(), vsigma_refs.back().data() ); else if( kern.is_mgga() ) - kern.eval_exc_vxc( npts, rho.data(), sigma.data(), - lapl.data(), tau.data(), eps_refs.back().data(), + kern.eval_exc_vxc( static_cast(npts), rho.data(), sigma.data(), + lapl.data(), tau.data(), eps_refs.back().data(), vrho_refs.back().data(), vsigma_refs.back().data(), vlapl_refs.back().data(), vtau_refs.back().data() ); diff --git a/test/xc_kernel_test.cxx b/test/xc_kernel_test.cxx index 143b489..4a328ee 100644 --- a/test/xc_kernel_test.cxx +++ b/test/xc_kernel_test.cxx @@ -974,7 +974,7 @@ void compare_libxc_builtin( TestInterface interface, EvalType evaltype, REQUIRE( npts_lda == npts_mgga ); REQUIRE( npts_lda == npts_lapl ); - const int npts = npts_lda; + const int npts = static_cast(npts_lda); XCKernel func_libxc ( Backend::libxc, kern, polar ); XCKernel func_builtin( Backend::builtin, kern, polar ); From 60160416446533f55d463a261419a41840374fa5 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 18:09:28 +0200 Subject: [PATCH 27/39] =?UTF-8?q?fix(msvc):=20C4530=20=E2=80=94=20add=20/E?= =?UTF-8?q?Hsc=20via=20add=5Fcompile=5Foptions=20in=20top-level=20CMakeLis?= =?UTF-8?q?ts.txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /EHsc was only on the exchcxx target's PUBLIC options; Catch2 is a separate CMake target compiled without it, triggering C4530 in and ppltasks.h during STL template instantiation. Using add_compile_options in the top-level CMakeLists.txt applies it globally to all targets (exchcxx, libxc, Catch2 via FetchContent). --- CMakeLists.txt | 6 ++++++ src/CMakeLists.txt | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac57e85..6796b15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,12 @@ include(FetchContent) # Set up project definition + version information project( ExchCXX VERSION 1.0.0 LANGUAGES C CXX ) +if(MSVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # Standard C++ exception-handling model — required by the STL and noexcept + # specifiers; must be global so FetchContent targets (Catch2, libxc) also get it. + add_compile_options(/EHsc) +endif() + # ExchCXX Options option( EXCHCXX_ENABLE_BENCHMARK "Enable Performance Benchmark" OFF ) option( EXCHCXX_ENABLE_CUDA "Enable Device Code (CUDA)" OFF ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 464a5f6..8b171e5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -49,7 +49,6 @@ if(MSVC) ) else() # cl target_compile_options( exchcxx PUBLIC - /EHsc # enable standard C++ exception-handling model (fixes C4577) /Zc:preprocessor # conforming preprocessor: empty macro args are valid (fixes C4003 via NOTYPE) /wd4800 # implicit double-to-bool: fires in auto-generated kernel headers, intentional /wd4514 # unreferenced inline removed: informational, level 4, linker dead-strips correctly From a5baf9bc82ca5e65cfb790ce74fd50e6d705f78c Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 18:23:32 +0200 Subject: [PATCH 28/39] =?UTF-8?q?fix(msvc):=20C4267=20=E2=80=94=20npts=20s?= =?UTF-8?q?hould=20be=20int=20not=20size=5Ft=20when=20sourced=20from=20ref?= =?UTF-8?q?=5Fvals.npts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ref_vals.npts is int; storing it in size_t then passing it back to eval_* (which takes int) is a pointless round-trip that triggers C4267. --- test/xc_kernel_test.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/xc_kernel_test.cxx b/test/xc_kernel_test.cxx index 4a328ee..5498c16 100644 --- a/test/xc_kernel_test.cxx +++ b/test/xc_kernel_test.cxx @@ -488,7 +488,7 @@ void kernel_test( TestInterface interface, Backend backend, Kernel kern, load_lda_reference_values( kern, polar ) : gen_lda_reference_values( backend,kern, polar ); - size_t npts = ref_vals.npts; + int npts = ref_vals.npts; const auto& rho = ref_vals.rho; const auto& exc_ref = ref_vals.exc; const auto& vrho_ref = ref_vals.vrho; @@ -577,7 +577,7 @@ void kernel_test( TestInterface interface, Backend backend, Kernel kern, load_gga_reference_values( kern, polar ) : gen_gga_reference_values( backend,kern, polar ); - size_t npts = ref_vals.npts; + int npts = ref_vals.npts; const auto& sigma = ref_vals.sigma; const auto& rho = ref_vals.rho; const auto& exc_ref = ref_vals.exc; @@ -695,7 +695,7 @@ void kernel_test( TestInterface interface, Backend backend, Kernel kern, //auto ref_vals = // gen_mgga_reference_values( backend,kern, polar ); - size_t npts = ref_vals.npts; + int npts = ref_vals.npts; const auto& rho = ref_vals.rho; const auto& sigma = ref_vals.sigma; const auto& lapl = ref_vals.lapl; From 49ac834190d3e257468f7922900f03cbfba665b6 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 18:35:16 +0200 Subject: [PATCH 29/39] refactor(clang-cl): align warning flags with MSVC policy Comment out all clang-cl -Wno-* suppressions that have no /wd* counterpart in the cl build; keep only -Wno-sign-conversion and -Wno-switch-enum which mirror /wd4365 and /wd4061 respectively. Add -Wall -Wextra as the clang-cl policy baseline (equivalent to the /W3 + mandatory /w1XXXX list used for cl); remove /W3 from CMAKE_CXX_FLAGS_RELEASE where it was misplaced. --- .gitignore | 1 + src/CMakeLists.txt | 55 ++++++++++++++++++++++++---------------------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index 514a186..dda5e57 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build .vscode *.*.swp +build*/ \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8b171e5..4d31631 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,32 +20,35 @@ if(MSVC) target_compile_definitions( exchcxx PUBLIC _USE_MATH_DEFINES ) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # clang-cl target_compile_options( exchcxx PUBLIC - -Wno-c++98-compat - -Wno-c++98-compat-local-type-template-args - -Wno-c++98-compat-pedantic - -Wno-deprecated-declarations - -Wno-exit-time-destructors - -Wno-extra-semi - -Wno-extra-semi-stmt - -Wno-float-conversion - -Wno-float-equal - -Wno-global-constructors - -Wno-inconsistent-missing-destructor-override - -Wno-missing-prototypes - -Wno-missing-variable-declarations - -Wno-old-style-cast - -Wno-pre-c++14-compat - -Wno-pre-c++17-compat - -Wno-reserved-macro-identifier - -Wno-sign-conversion - -Wno-suggest-destructor-override - -Wno-switch-enum - -Wno-undefined-func-template - -Wno-unsafe-buffer-usage - -Wno-unsafe-buffer-usage-in-libc-call - -Wno-unused-macros - -Wno-unused-parameter - -Wno-unused-variable + # --- active: mirror the /wd* suppressions used for cl --- + -Wno-sign-conversion # mirrors /wd4365: signed/unsigned in STL-heavy code + -Wno-switch-enum # mirrors /wd4061: intentional default: covers all kernels + + # --- under review: clang-specific, no cl counterpart --- + # -Wno-c++98-compat + # -Wno-c++98-compat-local-type-template-args + # -Wno-c++98-compat-pedantic + # -Wno-deprecated-declarations + # -Wno-exit-time-destructors + # -Wno-extra-semi + # -Wno-extra-semi-stmt + # -Wno-float-conversion + # -Wno-float-equal + # -Wno-global-constructors + # -Wno-inconsistent-missing-destructor-override + # -Wno-missing-prototypes + # -Wno-missing-variable-declarations + # -Wno-old-style-cast + # -Wno-pre-c++14-compat + # -Wno-pre-c++17-compat + # -Wno-reserved-macro-identifier + # -Wno-suggest-destructor-override + # -Wno-undefined-func-template + # -Wno-unsafe-buffer-usage + # -Wno-unsafe-buffer-usage-in-libc-call + # -Wno-unused-macros + # -Wno-unused-parameter + # -Wno-unused-variable ) else() # cl target_compile_options( exchcxx PUBLIC From 244fd150cee42fdd5db2c941eb15553de22edeee Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Thu, 28 May 2026 18:35:25 +0200 Subject: [PATCH 30/39] build(clang-cl): add -Wall -Wextra policy flags to build script --- exchcxx-build-clang-cl.ps1 | 181 +++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 exchcxx-build-clang-cl.ps1 diff --git a/exchcxx-build-clang-cl.ps1 b/exchcxx-build-clang-cl.ps1 new file mode 100644 index 0000000..9b7a504 --- /dev/null +++ b/exchcxx-build-clang-cl.ps1 @@ -0,0 +1,181 @@ +# exchcxx-build-clang.ps1 +# Build and test ExchCXX on Windows with clang-cl. +# Run from the ExchCXX repo root in a PowerShell. +# +# Usage: +# .\exchcxx-build-clang-cl.ps1 # Full build + test +# .\exchcxx-build-clang-cl.ps1 -SkipConfigure # Incremental build (skip cmake configure) +# .\exchcxx-build-clang-cl.ps1 -SkipTests # Build only, no tests + +param( + [switch]$SkipConfigure, + [switch]$SkipTests +) + +$ErrorActionPreference = "Stop" +$RepoRoot = $PSScriptRoot +$BuildDir = "$RepoRoot\build-clang-cl" + +$QdkRoot = "C:\Users\v-lercole\src\qdk-chemistry" +$VcpkgInstalledDir = "$QdkRoot\vcpkg_installed" +$VcpkgTriplet = "x64-windows-static-md" + +Write-Host "============================================" -ForegroundColor Cyan +Write-Host " ExchCXX - Windows (clang-cl) " -ForegroundColor Cyan +Write-Host "============================================" -ForegroundColor Cyan +Write-Host "Repo root: $RepoRoot" +Write-Host "" + +function Assert-Command($Name) { + if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) { + Write-Error "$Name not found in PATH. Please install it first." + exit 1 + } +} + +# -------------------------------------------------------------------------- +# Set up MSVC + clang-cl environment +# -------------------------------------------------------------------------- +$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" +$vsPath = & $vswhere -latest -products * -property installationPath 2>$null + +# Find clang-cl +$clangCl = $null +$candidates = @( + "$vsPath\VC\Tools\Llvm\x64\bin\clang-cl.exe", + "$vsPath\VC\Tools\Llvm\bin\clang-cl.exe" +) +foreach ($c in $candidates) { + if (Test-Path $c) { $clangCl = $c; break } +} +if (-not $clangCl) { + Write-Error "clang-cl not found. Install VS Build Tools with Clang component." + exit 1 +} +$clangDir = Split-Path $clangCl +$env:PATH = "$clangDir;$env:PATH" + +# Set up MSVC developer environment (vcvarsall) +$vcvarsall = "$vsPath\VC\Auxiliary\Build\vcvarsall.bat" +if (Test-Path $vcvarsall) { + $tempFile = [System.IO.Path]::GetTempFileName() + cmd /c "`"$vcvarsall`" x64 && set > `"$tempFile`"" + Get-Content $tempFile | ForEach-Object { + if ($_ -match "^([^=]+)=(.*)$") { + [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2], "Process") + } + } + Remove-Item $tempFile + # Re-add clang-cl to PATH (vcvarsall may have reset it) + $env:PATH = "$clangDir;$env:PATH" +} else { + Write-Error "vcvarsall.bat not found at $vcvarsall" + exit 1 +} + +# Set up vcpkg environment (reuse qdk-chemistry's vcpkg_installed) +$vcpkgRoot = $null +$vsVcpkg = "$vsPath\VC\vcpkg\vcpkg.exe" +if (Test-Path $vsVcpkg) { + $vcpkgRoot = Split-Path $vsVcpkg +} elseif ($env:VCPKG_INSTALLATION_ROOT -and (Test-Path "$($env:VCPKG_INSTALLATION_ROOT)\vcpkg.exe")) { + $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT +} else { + $vcpkgRoot = "$QdkRoot\vcpkg-tool" +} + +$toolchainFile = "$vcpkgRoot\scripts\buildsystems\vcpkg.cmake" +$env:CMAKE_TOOLCHAIN_FILE = $toolchainFile +$env:VCPKG_TARGET_TRIPLET = $VcpkgTriplet +$env:VCPKG_INSTALLED_DIR = $VcpkgInstalledDir +$env:CMAKE_PREFIX_PATH = "$VcpkgInstalledDir\$VcpkgTriplet" +$env:PATH = "$VcpkgInstalledDir\$VcpkgTriplet\bin;$VcpkgInstalledDir\$VcpkgTriplet\debug\bin;$env:PATH" + +# -------------------------------------------------------------------------- +# Verify environment +# -------------------------------------------------------------------------- +foreach ($cmd in @("clang-cl", "cmake", "ninja")) { + Assert-Command $cmd +} + +if (-not $env:CMAKE_TOOLCHAIN_FILE) { + Write-Error "CMAKE_TOOLCHAIN_FILE not set. Run qdk-chemistry's test-windows-build-msvc.ps1 -SkipCpp -SkipPython first to set up the environment." + exit 1 +} + +Write-Host "=== Environment ===" -ForegroundColor Yellow +Write-Host " clang-cl: $(Get-Command clang-cl | Select-Object -ExpandProperty Source)" +Write-Host " cmake: $(Get-Command cmake | Select-Object -ExpandProperty Source)" +Write-Host " ninja: $(Get-Command ninja | Select-Object -ExpandProperty Source)" +Write-Host " TOOLCHAIN_FILE: $env:CMAKE_TOOLCHAIN_FILE" +Write-Host " VCPKG_INSTALLED: $VcpkgInstalledDir" +Write-Host "" + +# -------------------------------------------------------------------------- +# Configure +# -------------------------------------------------------------------------- + +if (-not $SkipConfigure) { + Write-Host "=== Configure ===" -ForegroundColor Yellow + + cmake -S "$RepoRoot" -B "$BuildDir" ` + -GNinja ` + -DCMAKE_POLICY_VERSION_MINIMUM="3.5" ` + -DFETCHCONTENT_QUIET=OFF ` + -DBUILD_SHARED_LIBS=OFF ` + -DCMAKE_BUILD_TYPE=Release ` + -DCMAKE_CXX_STANDARD=20 ` + -DCMAKE_CXX_STANDARD_REQUIRED=ON ` + -DCMAKE_C_COMPILER=clang-cl ` + -DCMAKE_CXX_COMPILER=clang-cl ` + -DCMAKE_CXX_FLAGS="-Wall -Wextra" ` + -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` + -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` + -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` + -DVCPKG_INSTALLED_DIR="$VcpkgInstalledDir" ` + -DEXCHCXX_ENABLE_LIBXC=ON ` + -DEXCHCXX_ENABLE_CUDA=OFF ` + -DEXCHCXX_ENABLE_HIP=OFF ` + -DEXCHCXX_ENABLE_SYCL=OFF ` + -DEXCHCXX_ENABLE_TESTS=ON + if ($LASTEXITCODE -ne 0) { Write-Error "CMake configure failed"; exit 1 } + Write-Host "Configure succeeded." -ForegroundColor Green +} else { + Write-Host "=== Skipping configure (incremental build) ===" -ForegroundColor DarkGray + if (-not (Test-Path "$BuildDir\build.ninja")) { + Write-Error "No existing build found at $BuildDir. Run without -SkipConfigure first." + exit 1 + } +} + +# -------------------------------------------------------------------------- +# Build +# -------------------------------------------------------------------------- +Write-Host "" +Write-Host "=== Build ===" -ForegroundColor Yellow +cmake --build "$BuildDir" --parallel 6 2>&1 *> "$BuildDir\build.log" +if ($LASTEXITCODE -ne 0) { Write-Error "Build failed (see $BuildDir\build.log)"; exit 1 } +Write-Host "Build succeeded." -ForegroundColor Green + +# -------------------------------------------------------------------------- +# Test +# -------------------------------------------------------------------------- +if (-not $SkipTests) { + Write-Host "" + Write-Host "=== Test ===" -ForegroundColor Yellow + $env:OMP_NUM_THREADS = 4 + Push-Location "$BuildDir" + ctest --output-on-failure --verbose + $ctestExit = $LASTEXITCODE + Pop-Location + if ($ctestExit -ne 0) { + Write-Warning "Some tests failed (exit code: $ctestExit)" + } else { + Write-Host "All tests passed." -ForegroundColor Green + } +} + +Write-Host "" +Write-Host "============================================" -ForegroundColor Cyan +Write-Host " Done! " -ForegroundColor Cyan +Write-Host "============================================" -ForegroundColor Cyan From fff6bc95220607a7c77deceb2ac2d66d101b6066 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Fri, 29 May 2026 08:38:03 +0200 Subject: [PATCH 31/39] =?UTF-8?q?fix(clang-cl):=20extend=20/EHsc=20to=20cl?= =?UTF-8?q?ang-cl=20=E2=80=94=20both=20cl=20and=20clang-cl=20accept=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MSVC guard previously excluded clang-cl (CMAKE_CXX_COMPILER_ID=Clang), so exceptions were disabled and every 'throw' site failed to compile. --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6796b15..dbe7b78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,9 +4,10 @@ include(FetchContent) # Set up project definition + version information project( ExchCXX VERSION 1.0.0 LANGUAGES C CXX ) -if(MSVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") +if(MSVC) # Standard C++ exception-handling model — required by the STL and noexcept # specifiers; must be global so FetchContent targets (Catch2, libxc) also get it. + # Both cl and clang-cl accept /EHsc. add_compile_options(/EHsc) endif() From d92b80910b79db9640e4744ba8402508478af535 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Fri, 29 May 2026 10:33:15 +0200 Subject: [PATCH 32/39] build(clang-cl): reset the same CXX flags as the cl build script --- exchcxx-build-clang-cl.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exchcxx-build-clang-cl.ps1 b/exchcxx-build-clang-cl.ps1 index 9b7a504..d328af5 100644 --- a/exchcxx-build-clang-cl.ps1 +++ b/exchcxx-build-clang-cl.ps1 @@ -128,7 +128,7 @@ if (-not $SkipConfigure) { -DCMAKE_CXX_STANDARD_REQUIRED=ON ` -DCMAKE_C_COMPILER=clang-cl ` -DCMAKE_CXX_COMPILER=clang-cl ` - -DCMAKE_CXX_FLAGS="-Wall -Wextra" ` + -DCMAKE_CXX_FLAGS="/W3 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` From 945c055c20991b804c28c89d1b6bc4661bf593c9 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Fri, 29 May 2026 10:42:00 +0200 Subject: [PATCH 33/39] build(msvc): guard GCC/Clang developer warning flags behind if(NOT MSVC) Under clang-cl, -Wall maps to /Wall (= -Weverything), flooding the build with ~160k C++98-compat and other noise warnings. Policy-required flags are already set explicitly in the if(MSVC) block; the GCC/Clang developer set (-Wall -Wextra -Wpedantic -Wnon-virtual-dtor -Wshadow) must not apply. --- CMakeLists.txt | 2 ++ src/CMakeLists.txt | 44 +++++++++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dbe7b78..14400f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ include(FetchContent) # Set up project definition + version information project( ExchCXX VERSION 1.0.0 LANGUAGES C CXX ) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) if(MSVC) # Standard C++ exception-handling model — required by the STL and noexcept diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4d31631..db75ca3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -103,31 +103,33 @@ target_include_directories( exchcxx $ ) -include( CheckCXXCompilerFlag ) -check_cxx_compiler_flag( -Wall EXCHCXX_CXX_HAS_WALL ) -check_cxx_compiler_flag( -Wextra EXCHCXX_CXX_HAS_WEXTRA ) -check_cxx_compiler_flag( -Wpedantic EXCHCXX_CXX_HAS_WPEDANTIC ) -check_cxx_compiler_flag( -Wnon-virtual-dtor EXCHCXX_CXX_HAS_WNON_VIRTUAL_DTOR ) -check_cxx_compiler_flag( -Wshadow EXCHCXX_CXX_HAS_WSHADOW ) - -if( EXCHCXX_CXX_HAS_WALL ) - target_compile_options( exchcxx PRIVATE $<$: -Wall> ) -endif() +if(NOT MSVC) # under clang-cl, -Wall maps to /Wall (= -Weverything) + include( CheckCXXCompilerFlag ) + check_cxx_compiler_flag( -Wall EXCHCXX_CXX_HAS_WALL ) + check_cxx_compiler_flag( -Wextra EXCHCXX_CXX_HAS_WEXTRA ) + check_cxx_compiler_flag( -Wpedantic EXCHCXX_CXX_HAS_WPEDANTIC ) + check_cxx_compiler_flag( -Wnon-virtual-dtor EXCHCXX_CXX_HAS_WNON_VIRTUAL_DTOR ) + check_cxx_compiler_flag( -Wshadow EXCHCXX_CXX_HAS_WSHADOW ) + + if( EXCHCXX_CXX_HAS_WALL ) + target_compile_options( exchcxx PRIVATE $<$: -Wall> ) + endif() -if( EXCHCXX_CXX_HAS_WEXTRA ) - target_compile_options( exchcxx PRIVATE $<$: -Wextra> ) -endif() + if( EXCHCXX_CXX_HAS_WEXTRA ) + target_compile_options( exchcxx PRIVATE $<$: -Wextra> ) + endif() -if( EXCHCXX_CXX_HAS_WPEDANTIC ) - target_compile_options( exchcxx PRIVATE $<$: -Wpedantic> ) -endif() + if( EXCHCXX_CXX_HAS_WPEDANTIC ) + target_compile_options( exchcxx PRIVATE $<$: -Wpedantic> ) + endif() -if( EXCHCXX_CXX_HAS_WNON_VIRTUAL_DTOR ) - target_compile_options( exchcxx PRIVATE $<$: -Wnon-virtual-dtor -Werror=non-virtual-dtor> ) -endif() + if( EXCHCXX_CXX_HAS_WNON_VIRTUAL_DTOR ) + target_compile_options( exchcxx PRIVATE $<$: -Wnon-virtual-dtor -Werror=non-virtual-dtor> ) + endif() -if( EXCHCXX_CXX_HAS_WSHADOW ) - target_compile_options( exchcxx PRIVATE $<$: -Wshadow -Werror=shadow> ) + if( EXCHCXX_CXX_HAS_WSHADOW ) + target_compile_options( exchcxx PRIVATE $<$: -Wshadow -Werror=shadow> ) + endif() endif() # INSTALL rules From f92bed6a5135648d710748254156da25be278d55 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Fri, 29 May 2026 12:44:36 +0200 Subject: [PATCH 34/39] fix(clang-cl): suppress CRT deprecation warnings in FetchContent'd libxc libxc/src/functionals.c and version.c use strcpy/sscanf which MSVC and clang-cl flag as deprecated (-Wdeprecated-declarations / C4996). Add _CRT_SECURE_NO_WARNINGS as a PRIVATE compile definition on the xc target rather than touching upstream libxc sources. --- CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 14400f0..b07db7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,12 +99,16 @@ else() FetchContent_MakeAvailable( libxc ) add_library( Libxc::xc ALIAS xc ) - target_include_directories( xc - PUBLIC + target_include_directories( xc + PUBLIC $ $ $ ) + if(MSVC) + # Suppress CRT deprecation warnings (strcpy, sscanf, etc.) in libxc C sources + target_compile_definitions( xc PRIVATE _CRT_SECURE_NO_WARNINGS ) + endif() message( STATUS "Libxc Source: ${libxc_SOURCE_DIR}" ) # disable unity builds for libxc From 9bbf6eb25c2f02bf9661e2754ced56c8562d4822 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Fri, 29 May 2026 13:25:03 +0200 Subject: [PATCH 35/39] fix(msvc): add /permissive- globally to recognise C++ alternative tokens xc_kernel_test.cxx uses 'not' (ISO C++ alternative token for !). MSVC cl does not recognise it without conformance mode; /permissive- enables it alongside /EHsc in the top-level add_compile_options block. --- CMakeLists.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b07db7f..edcba2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,10 +7,11 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) if(MSVC) - # Standard C++ exception-handling model — required by the STL and noexcept - # specifiers; must be global so FetchContent targets (Catch2, libxc) also get it. - # Both cl and clang-cl accept /EHsc. - add_compile_options(/EHsc) + # /EHsc: standard C++ exception-handling model (required by STL and noexcept). + # /permissive-: conformance mode — recognises C++ alternative tokens (not, and, or, …). + # Both flags are accepted by cl and clang-cl; applied globally so FetchContent + # targets (Catch2, libxc) inherit them too. + add_compile_options(/EHsc /permissive-) endif() # ExchCXX Options From 79dfa6de5f459cbd48e887d690e6a8ba1e84565a Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Fri, 29 May 2026 16:14:30 +0200 Subject: [PATCH 36/39] cleanup --- exchcxx-build-clang-cl.ps1 | 181 ------------------------------------- exchcxx-build-msvc.ps1 | 159 -------------------------------- src/CMakeLists.txt | 87 ++++++------------ 3 files changed, 29 insertions(+), 398 deletions(-) delete mode 100644 exchcxx-build-clang-cl.ps1 delete mode 100644 exchcxx-build-msvc.ps1 diff --git a/exchcxx-build-clang-cl.ps1 b/exchcxx-build-clang-cl.ps1 deleted file mode 100644 index d328af5..0000000 --- a/exchcxx-build-clang-cl.ps1 +++ /dev/null @@ -1,181 +0,0 @@ -# exchcxx-build-clang.ps1 -# Build and test ExchCXX on Windows with clang-cl. -# Run from the ExchCXX repo root in a PowerShell. -# -# Usage: -# .\exchcxx-build-clang-cl.ps1 # Full build + test -# .\exchcxx-build-clang-cl.ps1 -SkipConfigure # Incremental build (skip cmake configure) -# .\exchcxx-build-clang-cl.ps1 -SkipTests # Build only, no tests - -param( - [switch]$SkipConfigure, - [switch]$SkipTests -) - -$ErrorActionPreference = "Stop" -$RepoRoot = $PSScriptRoot -$BuildDir = "$RepoRoot\build-clang-cl" - -$QdkRoot = "C:\Users\v-lercole\src\qdk-chemistry" -$VcpkgInstalledDir = "$QdkRoot\vcpkg_installed" -$VcpkgTriplet = "x64-windows-static-md" - -Write-Host "============================================" -ForegroundColor Cyan -Write-Host " ExchCXX - Windows (clang-cl) " -ForegroundColor Cyan -Write-Host "============================================" -ForegroundColor Cyan -Write-Host "Repo root: $RepoRoot" -Write-Host "" - -function Assert-Command($Name) { - if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) { - Write-Error "$Name not found in PATH. Please install it first." - exit 1 - } -} - -# -------------------------------------------------------------------------- -# Set up MSVC + clang-cl environment -# -------------------------------------------------------------------------- -$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -$vsPath = & $vswhere -latest -products * -property installationPath 2>$null - -# Find clang-cl -$clangCl = $null -$candidates = @( - "$vsPath\VC\Tools\Llvm\x64\bin\clang-cl.exe", - "$vsPath\VC\Tools\Llvm\bin\clang-cl.exe" -) -foreach ($c in $candidates) { - if (Test-Path $c) { $clangCl = $c; break } -} -if (-not $clangCl) { - Write-Error "clang-cl not found. Install VS Build Tools with Clang component." - exit 1 -} -$clangDir = Split-Path $clangCl -$env:PATH = "$clangDir;$env:PATH" - -# Set up MSVC developer environment (vcvarsall) -$vcvarsall = "$vsPath\VC\Auxiliary\Build\vcvarsall.bat" -if (Test-Path $vcvarsall) { - $tempFile = [System.IO.Path]::GetTempFileName() - cmd /c "`"$vcvarsall`" x64 && set > `"$tempFile`"" - Get-Content $tempFile | ForEach-Object { - if ($_ -match "^([^=]+)=(.*)$") { - [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2], "Process") - } - } - Remove-Item $tempFile - # Re-add clang-cl to PATH (vcvarsall may have reset it) - $env:PATH = "$clangDir;$env:PATH" -} else { - Write-Error "vcvarsall.bat not found at $vcvarsall" - exit 1 -} - -# Set up vcpkg environment (reuse qdk-chemistry's vcpkg_installed) -$vcpkgRoot = $null -$vsVcpkg = "$vsPath\VC\vcpkg\vcpkg.exe" -if (Test-Path $vsVcpkg) { - $vcpkgRoot = Split-Path $vsVcpkg -} elseif ($env:VCPKG_INSTALLATION_ROOT -and (Test-Path "$($env:VCPKG_INSTALLATION_ROOT)\vcpkg.exe")) { - $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT -} else { - $vcpkgRoot = "$QdkRoot\vcpkg-tool" -} - -$toolchainFile = "$vcpkgRoot\scripts\buildsystems\vcpkg.cmake" -$env:CMAKE_TOOLCHAIN_FILE = $toolchainFile -$env:VCPKG_TARGET_TRIPLET = $VcpkgTriplet -$env:VCPKG_INSTALLED_DIR = $VcpkgInstalledDir -$env:CMAKE_PREFIX_PATH = "$VcpkgInstalledDir\$VcpkgTriplet" -$env:PATH = "$VcpkgInstalledDir\$VcpkgTriplet\bin;$VcpkgInstalledDir\$VcpkgTriplet\debug\bin;$env:PATH" - -# -------------------------------------------------------------------------- -# Verify environment -# -------------------------------------------------------------------------- -foreach ($cmd in @("clang-cl", "cmake", "ninja")) { - Assert-Command $cmd -} - -if (-not $env:CMAKE_TOOLCHAIN_FILE) { - Write-Error "CMAKE_TOOLCHAIN_FILE not set. Run qdk-chemistry's test-windows-build-msvc.ps1 -SkipCpp -SkipPython first to set up the environment." - exit 1 -} - -Write-Host "=== Environment ===" -ForegroundColor Yellow -Write-Host " clang-cl: $(Get-Command clang-cl | Select-Object -ExpandProperty Source)" -Write-Host " cmake: $(Get-Command cmake | Select-Object -ExpandProperty Source)" -Write-Host " ninja: $(Get-Command ninja | Select-Object -ExpandProperty Source)" -Write-Host " TOOLCHAIN_FILE: $env:CMAKE_TOOLCHAIN_FILE" -Write-Host " VCPKG_INSTALLED: $VcpkgInstalledDir" -Write-Host "" - -# -------------------------------------------------------------------------- -# Configure -# -------------------------------------------------------------------------- - -if (-not $SkipConfigure) { - Write-Host "=== Configure ===" -ForegroundColor Yellow - - cmake -S "$RepoRoot" -B "$BuildDir" ` - -GNinja ` - -DCMAKE_POLICY_VERSION_MINIMUM="3.5" ` - -DFETCHCONTENT_QUIET=OFF ` - -DBUILD_SHARED_LIBS=OFF ` - -DCMAKE_BUILD_TYPE=Release ` - -DCMAKE_CXX_STANDARD=20 ` - -DCMAKE_CXX_STANDARD_REQUIRED=ON ` - -DCMAKE_C_COMPILER=clang-cl ` - -DCMAKE_CXX_COMPILER=clang-cl ` - -DCMAKE_CXX_FLAGS="/W3 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` - -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` - -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` - -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` - -DVCPKG_INSTALLED_DIR="$VcpkgInstalledDir" ` - -DEXCHCXX_ENABLE_LIBXC=ON ` - -DEXCHCXX_ENABLE_CUDA=OFF ` - -DEXCHCXX_ENABLE_HIP=OFF ` - -DEXCHCXX_ENABLE_SYCL=OFF ` - -DEXCHCXX_ENABLE_TESTS=ON - if ($LASTEXITCODE -ne 0) { Write-Error "CMake configure failed"; exit 1 } - Write-Host "Configure succeeded." -ForegroundColor Green -} else { - Write-Host "=== Skipping configure (incremental build) ===" -ForegroundColor DarkGray - if (-not (Test-Path "$BuildDir\build.ninja")) { - Write-Error "No existing build found at $BuildDir. Run without -SkipConfigure first." - exit 1 - } -} - -# -------------------------------------------------------------------------- -# Build -# -------------------------------------------------------------------------- -Write-Host "" -Write-Host "=== Build ===" -ForegroundColor Yellow -cmake --build "$BuildDir" --parallel 6 2>&1 *> "$BuildDir\build.log" -if ($LASTEXITCODE -ne 0) { Write-Error "Build failed (see $BuildDir\build.log)"; exit 1 } -Write-Host "Build succeeded." -ForegroundColor Green - -# -------------------------------------------------------------------------- -# Test -# -------------------------------------------------------------------------- -if (-not $SkipTests) { - Write-Host "" - Write-Host "=== Test ===" -ForegroundColor Yellow - $env:OMP_NUM_THREADS = 4 - Push-Location "$BuildDir" - ctest --output-on-failure --verbose - $ctestExit = $LASTEXITCODE - Pop-Location - if ($ctestExit -ne 0) { - Write-Warning "Some tests failed (exit code: $ctestExit)" - } else { - Write-Host "All tests passed." -ForegroundColor Green - } -} - -Write-Host "" -Write-Host "============================================" -ForegroundColor Cyan -Write-Host " Done! " -ForegroundColor Cyan -Write-Host "============================================" -ForegroundColor Cyan diff --git a/exchcxx-build-msvc.ps1 b/exchcxx-build-msvc.ps1 deleted file mode 100644 index 0e61e4b..0000000 --- a/exchcxx-build-msvc.ps1 +++ /dev/null @@ -1,159 +0,0 @@ -# exchcxx-build-msvc.ps1 -# Build and test ExchCXX on Windows with MSVC native cl.exe. -# Run from the ExchCXX repo root in a PowerShell. -# -# Usage: -# .\exchcxx-build-msvc.ps1 # Full build + test -# .\exchcxx-build-msvc.ps1 -SkipConfigure # Incremental build (skip cmake configure) -# .\exchcxx-build-msvc.ps1 -SkipTests # Build only, no tests - -param( - [switch]$SkipConfigure, - [switch]$SkipTests -) - -$ErrorActionPreference = "Stop" -$RepoRoot = $PSScriptRoot -$BuildDir = "$RepoRoot\build-msvc" -$QdkRoot = "C:\Users\v-lercole\src\qdk-chemistry" -$VcpkgInstalledDir = "$QdkRoot\vcpkg_installed" -$VcpkgTriplet = "x64-windows-static-md" - -Write-Host "============================================" -ForegroundColor Cyan -Write-Host " ExchCXX - Windows Build (MSVC) " -ForegroundColor Cyan -Write-Host "============================================" -ForegroundColor Cyan -Write-Host "Repo root: $RepoRoot" -Write-Host "" - -function Assert-Command($Name) { - if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) { - Write-Error "$Name not found in PATH. Please install it first." - exit 1 - } -} - -# -------------------------------------------------------------------------- -# Set up MSVC environment -# -------------------------------------------------------------------------- -$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -$vsPath = & $vswhere -latest -products * -property installationPath 2>$null - -# Set up MSVC developer environment (vcvarsall) -$vcvarsall = "$vsPath\VC\Auxiliary\Build\vcvarsall.bat" -if (Test-Path $vcvarsall) { - $tempFile = [System.IO.Path]::GetTempFileName() - cmd /c "`"$vcvarsall`" x64 && set > `"$tempFile`"" - Get-Content $tempFile | ForEach-Object { - if ($_ -match "^([^=]+)=(.*)$") { - [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2], "Process") - } - } - Remove-Item $tempFile -} - -# Set up vcpkg environment (reuse qdk-chemistry's vcpkg_installed) -$vcpkgRoot = $null -$vsVcpkg = "$vsPath\VC\vcpkg\vcpkg.exe" -if (Test-Path $vsVcpkg) { - $vcpkgRoot = Split-Path $vsVcpkg -} elseif ($env:VCPKG_INSTALLATION_ROOT -and (Test-Path "$($env:VCPKG_INSTALLATION_ROOT)\vcpkg.exe")) { - $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT -} else { - $vcpkgRoot = "$QdkRoot\vcpkg-tool" -} - -$toolchainFile = "$vcpkgRoot\scripts\buildsystems\vcpkg.cmake" -$env:CMAKE_TOOLCHAIN_FILE = $toolchainFile -$env:VCPKG_TARGET_TRIPLET = $VcpkgTriplet -$env:VCPKG_INSTALLED_DIR = $VcpkgInstalledDir -$env:CMAKE_PREFIX_PATH = "$VcpkgInstalledDir\$VcpkgTriplet" -$env:PATH = "$VcpkgInstalledDir\$VcpkgTriplet\bin;$VcpkgInstalledDir\$VcpkgTriplet\debug\bin;$env:PATH" - -# -------------------------------------------------------------------------- -# Verify environment -# -------------------------------------------------------------------------- -foreach ($cmd in @("cl", "cmake", "ninja")) { - Assert-Command $cmd -} - -if (-not $env:CMAKE_TOOLCHAIN_FILE) { - Write-Error "CMAKE_TOOLCHAIN_FILE not set. Run qdk-chemistry's test-windows-build-msvc.ps1 -SkipCpp -SkipPython first to set up the environment." - exit 1 -} - -Write-Host "=== Environment ===" -ForegroundColor Yellow -Write-Host " cl: $(Get-Command cl | Select-Object -ExpandProperty Source)" -Write-Host " cmake: $(Get-Command cmake | Select-Object -ExpandProperty Source)" -Write-Host " ninja: $(Get-Command ninja | Select-Object -ExpandProperty Source)" -Write-Host " TOOLCHAIN_FILE: $env:CMAKE_TOOLCHAIN_FILE" -Write-Host " VCPKG_INSTALLED: $VcpkgInstalledDir" -Write-Host "" - -# -------------------------------------------------------------------------- -# Configure -# -------------------------------------------------------------------------- - -if (-not $SkipConfigure) { - Write-Host "=== Configure ===" -ForegroundColor Yellow - - cmake -S "$RepoRoot" -B "$BuildDir" ` - -GNinja ` - -DCMAKE_POLICY_VERSION_MINIMUM="3.5" ` - -DFETCHCONTENT_QUIET=OFF ` - -DBUILD_SHARED_LIBS=OFF ` - -DCMAKE_BUILD_TYPE=Release ` - -DCMAKE_CXX_STANDARD=20 ` - -DCMAKE_CXX_STANDARD_REQUIRED=ON ` - -DCMAKE_C_COMPILER=cl ` - -DCMAKE_CXX_COMPILER=cl ` - -DCMAKE_CXX_FLAGS="/W3 /w14018 /w14055 /w14100 /w14102 /w14127 /w14146 /w14242 /w14244 /w14245 /w14254 /w14267 /w14302 /w14306 /w14308 /w14310 /w14389 /w14509 /w14510 /w14512 /w14532 /w14533 /w14610 /w14611 /w14700 /w14701 /w14703 /w14789 /w14995 /w14996" ` - -DCMAKE_CXX_FLAGS_RELEASE="/O2 /DNDEBUG" ` - -DCMAKE_TOOLCHAIN_FILE="$env:CMAKE_TOOLCHAIN_FILE" ` - -DVCPKG_TARGET_TRIPLET=$VcpkgTriplet ` - -DVCPKG_INSTALLED_DIR="$VcpkgInstalledDir" ` - -DEXCHCXX_ENABLE_LIBXC=ON ` - -DEXCHCXX_ENABLE_CUDA=OFF ` - -DEXCHCXX_ENABLE_HIP=OFF ` - -DEXCHCXX_ENABLE_SYCL=OFF ` - -DEXCHCXX_ENABLE_TESTS=ON - if ($LASTEXITCODE -ne 0) { Write-Error "CMake configure failed"; exit 1 } - Write-Host "Configure succeeded." -ForegroundColor Green -} else { - Write-Host "=== Skipping configure (incremental build) ===" -ForegroundColor DarkGray - if (-not (Test-Path "$BuildDir\build.ninja")) { - Write-Error "No existing build found at $BuildDir. Run without -SkipConfigure first." - exit 1 - } -} - -# -------------------------------------------------------------------------- -# Build -# -------------------------------------------------------------------------- -Write-Host "" -Write-Host "=== Build ===" -ForegroundColor Yellow -cmake --build "$BuildDir" --parallel 6 2>&1 *> "$BuildDir\build.log" -if ($LASTEXITCODE -ne 0) { Write-Error "Build failed (see $BuildDir\build.log)"; exit 1 } -Write-Host "Build succeeded." -ForegroundColor Green - -# -------------------------------------------------------------------------- -# Test -# -------------------------------------------------------------------------- -if (-not $SkipTests) { - Write-Host "" - Write-Host "=== Test ===" -ForegroundColor Yellow - $env:OMP_NUM_THREADS = 4 - Push-Location "$BuildDir" - ctest --output-on-failure --verbose - $ctestExit = $LASTEXITCODE - Pop-Location - if ($ctestExit -ne 0) { - Write-Warning "Some tests failed (exit code: $ctestExit)" - } else { - Write-Host "All tests passed." -ForegroundColor Green - } -} - -Write-Host "" -Write-Host "============================================" -ForegroundColor Cyan -Write-Host " Done! " -ForegroundColor Cyan -Write-Host "============================================" -ForegroundColor Cyan diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index db75ca3..70f3a01 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,50 +20,24 @@ if(MSVC) target_compile_definitions( exchcxx PUBLIC _USE_MATH_DEFINES ) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # clang-cl target_compile_options( exchcxx PUBLIC - # --- active: mirror the /wd* suppressions used for cl --- -Wno-sign-conversion # mirrors /wd4365: signed/unsigned in STL-heavy code -Wno-switch-enum # mirrors /wd4061: intentional default: covers all kernels - - # --- under review: clang-specific, no cl counterpart --- - # -Wno-c++98-compat - # -Wno-c++98-compat-local-type-template-args - # -Wno-c++98-compat-pedantic - # -Wno-deprecated-declarations - # -Wno-exit-time-destructors - # -Wno-extra-semi - # -Wno-extra-semi-stmt - # -Wno-float-conversion - # -Wno-float-equal - # -Wno-global-constructors - # -Wno-inconsistent-missing-destructor-override - # -Wno-missing-prototypes - # -Wno-missing-variable-declarations - # -Wno-old-style-cast - # -Wno-pre-c++14-compat - # -Wno-pre-c++17-compat - # -Wno-reserved-macro-identifier - # -Wno-suggest-destructor-override - # -Wno-undefined-func-template - # -Wno-unsafe-buffer-usage - # -Wno-unsafe-buffer-usage-in-libc-call - # -Wno-unused-macros - # -Wno-unused-parameter - # -Wno-unused-variable ) else() # cl + # silence noisy level-4 warnings that appear because STL raises the level to 4 during template instantiations target_compile_options( exchcxx PUBLIC /Zc:preprocessor # conforming preprocessor: empty macro args are valid (fixes C4003 via NOTYPE) - /wd4800 # implicit double-to-bool: fires in auto-generated kernel headers, intentional - /wd4514 # unreferenced inline removed: informational, level 4, linker dead-strips correctly - /wd4710 # function not inlined: informational, level 4, optimizer decision - /wd4711 # function auto-inlined: informational, level 4, optimizer decision /wd4061 # enumerator not in switch case: intentional default: handler covers all kernels /wd4266 # no override for virtual function: by-design partial override in APPROX specialisations - /wd4702 # unreachable code: macro-expanded dispatch tables, not real dead code /wd4365 # signed/unsigned in STL code: safe, values always non-negative - /wd5045 # Spectre mitigation remark: informational, /Qspectre not in use - /wd4820 # struct padding: ABI layout decision, informational + /wd4514 # unreferenced inline removed: informational, linker dead-strips correctly /wd4626 # assignment operator deleted: by-design non-copyable classes with reference members + /wd4702 # unreachable code: macro-expanded dispatch tables, not real dead code + /wd4710 # function not inlined: informational, optimizer decision + /wd4711 # function auto-inlined: informational, optimizer decision + /wd4800 # implicit double-to-bool: fires in auto-generated kernel headers, intentional + /wd4820 # struct padding: ABI layout decision, informational + /wd5045 # Spectre mitigation remark: informational, /Qspectre not in use ) endif() endif() @@ -79,7 +53,6 @@ configure_file( target_compile_definitions( exchcxx PUBLIC "EXCHCXX_HAS_CONFIG_H=1" ) - # Device specific if( EXCHCXX_ENABLE_CUDA ) include( cuda/exchcxx_cuda.cmake ) @@ -94,7 +67,6 @@ if( EXCHCXX_ENABLE_SYCL ) endif() - target_include_directories( exchcxx PUBLIC $ @@ -103,39 +75,39 @@ target_include_directories( exchcxx $ ) +include( CheckCXXCompilerFlag ) if(NOT MSVC) # under clang-cl, -Wall maps to /Wall (= -Weverything) - include( CheckCXXCompilerFlag ) check_cxx_compiler_flag( -Wall EXCHCXX_CXX_HAS_WALL ) - check_cxx_compiler_flag( -Wextra EXCHCXX_CXX_HAS_WEXTRA ) - check_cxx_compiler_flag( -Wpedantic EXCHCXX_CXX_HAS_WPEDANTIC ) - check_cxx_compiler_flag( -Wnon-virtual-dtor EXCHCXX_CXX_HAS_WNON_VIRTUAL_DTOR ) - check_cxx_compiler_flag( -Wshadow EXCHCXX_CXX_HAS_WSHADOW ) +endif() +check_cxx_compiler_flag( -Wextra EXCHCXX_CXX_HAS_WEXTRA ) +check_cxx_compiler_flag( -Wpedantic EXCHCXX_CXX_HAS_WPEDANTIC ) +check_cxx_compiler_flag( -Wnon-virtual-dtor EXCHCXX_CXX_HAS_WNON_VIRTUAL_DTOR ) +check_cxx_compiler_flag( -Wshadow EXCHCXX_CXX_HAS_WSHADOW ) - if( EXCHCXX_CXX_HAS_WALL ) - target_compile_options( exchcxx PRIVATE $<$: -Wall> ) - endif() +if( EXCHCXX_CXX_HAS_WALL ) + target_compile_options( exchcxx PRIVATE $<$: -Wall> ) +endif() - if( EXCHCXX_CXX_HAS_WEXTRA ) - target_compile_options( exchcxx PRIVATE $<$: -Wextra> ) - endif() +if( EXCHCXX_CXX_HAS_WEXTRA ) + target_compile_options( exchcxx PRIVATE $<$: -Wextra> ) +endif() - if( EXCHCXX_CXX_HAS_WPEDANTIC ) - target_compile_options( exchcxx PRIVATE $<$: -Wpedantic> ) - endif() +if( EXCHCXX_CXX_HAS_WPEDANTIC ) + target_compile_options( exchcxx PRIVATE $<$: -Wpedantic> ) +endif() - if( EXCHCXX_CXX_HAS_WNON_VIRTUAL_DTOR ) - target_compile_options( exchcxx PRIVATE $<$: -Wnon-virtual-dtor -Werror=non-virtual-dtor> ) - endif() +if( EXCHCXX_CXX_HAS_WNON_VIRTUAL_DTOR ) + target_compile_options( exchcxx PRIVATE $<$: -Wnon-virtual-dtor -Werror=non-virtual-dtor> ) +endif() - if( EXCHCXX_CXX_HAS_WSHADOW ) - target_compile_options( exchcxx PRIVATE $<$: -Wshadow -Werror=shadow> ) - endif() +if( EXCHCXX_CXX_HAS_WSHADOW ) + target_compile_options( exchcxx PRIVATE $<$: -Wshadow -Werror=shadow> ) endif() + # INSTALL rules add_library( ExchCXX::ExchCXX ALIAS exchcxx ) - include( GNUInstallDirs ) set( INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/ExchCXX ) @@ -146,7 +118,6 @@ install(TARGETS exchcxx ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) - set_target_properties( exchcxx PROPERTIES EXPORT_NAME ExchCXX ) # Install Headers From ace341e304969fe2f0a12f04872da0a1d08df1f9 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Fri, 29 May 2026 16:52:04 +0200 Subject: [PATCH 37/39] fix: npts should be size_t in XCKernel Metadata Validity test buffer_len functions take and return size_t; using int caused an implicit narrowing conversion on the argument and a signed/unsigned mismatch in the equality checks. --- test/xc_kernel_test.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/xc_kernel_test.cxx b/test/xc_kernel_test.cxx index 5498c16..a08cd76 100644 --- a/test/xc_kernel_test.cxx +++ b/test/xc_kernel_test.cxx @@ -56,7 +56,7 @@ using namespace ExchCXX; TEST_CASE( "XCKernel Metadata Validity", "[xc-kernel]" ) { - const int npts = 1024; + const size_t npts = 1024; auto lda_kernel_test = Kernel::SlaterExchange; auto gga_kernel_test = Kernel::LYP; From c79b7696f0b7ce334549ecfc91063a49fbf58a29 Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Fri, 29 May 2026 17:03:55 +0200 Subject: [PATCH 38/39] fix(msvc): scope /EHsc and /permissive- to CXX only add_compile_options without a language guard applies flags to all languages including C (libxc sources). Use COMPILE_LANGUAGE:CXX generator expressions so the C++-only flags don't affect C compilation. --- CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index edcba2a..65873ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,9 +9,11 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) if(MSVC) # /EHsc: standard C++ exception-handling model (required by STL and noexcept). # /permissive-: conformance mode — recognises C++ alternative tokens (not, and, or, …). - # Both flags are accepted by cl and clang-cl; applied globally so FetchContent - # targets (Catch2, libxc) inherit them too. - add_compile_options(/EHsc /permissive-) + # Scoped to CXX only so libxc's C sources are not affected. + add_compile_options( + $<$:/EHsc> + $<$:/permissive-> + ) endif() # ExchCXX Options From 20a2d6052bc5b1bac4a0d028f3735056e5345dac Mon Sep 17 00:00:00 2001 From: Loris Ercole Date: Fri, 29 May 2026 17:30:13 +0200 Subject: [PATCH 39/39] fix(msvc): make warning-suppression flags PRIVATE on exchcxx target /wd* flags and -Wno-* are build-hygiene settings for ExchCXX's own sources and must not propagate to downstream consumers via PUBLIC. /Zc:preprocessor stays PUBLIC because the public headers use the NOTYPE empty macro which requires the conforming preprocessor on consumers too. _USE_MATH_DEFINES stays PUBLIC for the same reason (M_PI in public headers). --- src/CMakeLists.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 70f3a01..6faed6c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,14 +19,16 @@ target_compile_features( exchcxx PUBLIC cxx_std_17 ) if(MSVC) target_compile_definitions( exchcxx PUBLIC _USE_MATH_DEFINES ) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # clang-cl - target_compile_options( exchcxx PUBLIC + target_compile_options( exchcxx PRIVATE -Wno-sign-conversion # mirrors /wd4365: signed/unsigned in STL-heavy code -Wno-switch-enum # mirrors /wd4061: intentional default: covers all kernels ) else() # cl - # silence noisy level-4 warnings that appear because STL raises the level to 4 during template instantiations target_compile_options( exchcxx PUBLIC - /Zc:preprocessor # conforming preprocessor: empty macro args are valid (fixes C4003 via NOTYPE) + /Zc:preprocessor # PUBLIC: public headers use NOTYPE empty macro; consumers need conforming preprocessor + ) + # silence noisy level-4 warnings that appear because STL raises the level to 4 during template instantiations + target_compile_options( exchcxx PRIVATE /wd4061 # enumerator not in switch case: intentional default: handler covers all kernels /wd4266 # no override for virtual function: by-design partial override in APPROX specialisations /wd4365 # signed/unsigned in STL code: safe, values always non-negative