From 46c827c7fc3f344b6be28692b25aa5d04659291d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Fri, 28 Jan 2022 14:51:08 +0100 Subject: [PATCH 1/2] Fixed Clang 12 compiler warnings. --- CMakeLists.txt | 5 +++++ src/libslic3r/Fill/FillRectilinear.cpp | 2 +- src/libslic3r/Model.cpp | 2 +- src/libslic3r/MultiPoint.hpp | 3 ++- src/libslic3r/Polygon.hpp | 2 +- src/libslic3r/Polyline.hpp | 3 ++- src/slic3r/GUI/FirmwareDialog.cpp | 2 +- src/slic3r/GUI/OptionsGroup.hpp | 3 ++- 8 files changed, 15 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8557ab0d7d..441d09af9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -239,6 +239,11 @@ if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMP add_compile_options(-Wno-deprecated-declarations) endif() + # Clang reports misleading indentation for some IF blocks because of mixing tabs with spaces. + if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + add_compile_options(-Wno-misleading-indentation) + endif() + #GCC generates loads of -Wunknown-pragmas when compiling igl. The fix is not easy due to a bug in gcc, see # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66943 or # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431 diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index 69476175e0..7d868860a7 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -2391,7 +2391,7 @@ static std::vector chain_monotonic_regions( // Probability (unnormalized) of traversing a link between two monotonic regions. auto path_probability = [ -#ifndef __APPLE__ +#if !defined(__APPLE__) && !defined(__clang__) // clang complains when capturing constexpr constants. pheromone_alpha, pheromone_beta #endif // __APPLE__ diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index efc66f4781..67450fb116 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -2264,7 +2264,7 @@ void check_model_ids_validity(const Model &model) for (const ModelInstance *model_instance : model_object->instances) check(model_instance->id()); } - for (const auto mm : model.materials) { + for (const auto &mm : model.materials) { check(mm.second->id()); check(mm.second->config.id()); } diff --git a/src/libslic3r/MultiPoint.hpp b/src/libslic3r/MultiPoint.hpp index 935348279c..b5208b1d8b 100644 --- a/src/libslic3r/MultiPoint.hpp +++ b/src/libslic3r/MultiPoint.hpp @@ -17,7 +17,8 @@ class MultiPoint public: Points points; - MultiPoint() {} + MultiPoint() = default; + virtual ~MultiPoint() = default; MultiPoint(const MultiPoint &other) : points(other.points) {} MultiPoint(MultiPoint &&other) : points(std::move(other.points)) {} MultiPoint(std::initializer_list list) : points(list) {} diff --git a/src/libslic3r/Polygon.hpp b/src/libslic3r/Polygon.hpp index 7d34e3aaec..d245403392 100644 --- a/src/libslic3r/Polygon.hpp +++ b/src/libslic3r/Polygon.hpp @@ -19,7 +19,7 @@ class Polygon : public MultiPoint { public: Polygon() = default; - virtual ~Polygon() = default; + ~Polygon() override = default; explicit Polygon(const Points &points) : MultiPoint(points) {} Polygon(std::initializer_list points) : MultiPoint(points) {} Polygon(const Polygon &other) : MultiPoint(other.points) {} diff --git a/src/libslic3r/Polyline.hpp b/src/libslic3r/Polyline.hpp index 31e0b88d32..5766d9671b 100644 --- a/src/libslic3r/Polyline.hpp +++ b/src/libslic3r/Polyline.hpp @@ -16,7 +16,8 @@ typedef std::vector ThickPolylines; class Polyline : public MultiPoint { public: - Polyline() {}; + Polyline() = default; + ~Polyline() override = default; Polyline(const Polyline &other) : MultiPoint(other.points) {} Polyline(Polyline &&other) : MultiPoint(std::move(other.points)) {} Polyline(std::initializer_list list) : MultiPoint(list) {} diff --git a/src/slic3r/GUI/FirmwareDialog.cpp b/src/slic3r/GUI/FirmwareDialog.cpp index 7600ef4fa6..47402644f4 100644 --- a/src/slic3r/GUI/FirmwareDialog.cpp +++ b/src/slic3r/GUI/FirmwareDialog.cpp @@ -654,7 +654,7 @@ void FirmwareDialog::priv::perform_upload() } }) .on_message([ -#ifndef __APPLE__ +#if !defined(__APPLE__) && !defined(__clang__) // clang complains when capturing constants. extra_verbose, #endif // __APPLE__ diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 61a59f0e3b..f3efd06807 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -185,7 +185,7 @@ public: OptionsGroup( wxWindow* _parent, const wxString& title, bool is_tab_opt = false, column_t extra_clmn = nullptr); - ~OptionsGroup() { clear(true); } + virtual ~OptionsGroup() { clear(true); } wxGridSizer* get_grid_sizer() { return m_grid_sizer; } const std::vector& get_lines() { return m_lines; } @@ -253,6 +253,7 @@ public: OptionsGroup(parent, title, is_tab_opt, extra_clmn), m_config(&config->get()), m_modelconfig(config) {} ConfigOptionsGroup( wxWindow* parent) : OptionsGroup(parent, wxEmptyString, true, nullptr) {} + ~ConfigOptionsGroup() override = default; const wxString& config_category() const throw() { return m_config_category; } int config_type() const throw() { return m_config_type; } From 5f0fea4d58f558bb64681d28c8e10c6392b48629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Fri, 28 Jan 2022 14:51:34 +0100 Subject: [PATCH 2/2] Added option to enable UndefinedBehaviorSanitizer on Clang and GCC. --- CMakeLists.txt | 27 +++++++++++++++++++++++++++ deps/Boost/Boost.cmake | 6 ++++++ deps/Boost/Boost.patch | 23 +++++++++++++++++++++++ src/PrusaSlicer.cpp | 9 +++++++++ src/libslic3r/Int128.hpp | 5 +++++ 5 files changed, 70 insertions(+) create mode 100644 deps/Boost/Boost.patch diff --git a/CMakeLists.txt b/CMakeLists.txt index 441d09af9b..72fd87d224 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1) option(SLIC3R_MSVC_PDB "Generate PDB files on MSVC in Release mode" 1) option(SLIC3R_PERL_XS "Compile XS Perl module and enable Perl unit and integration tests" 0) option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0) +option(SLIC3R_UBSAN "Enable UBSan on Clang and GCC" 0) # If SLIC3R_FHS is 1 -> SLIC3R_DESKTOP_INTEGRATION is always 0, othrewise variable. CMAKE_DEPENDENT_OPTION(SLIC3R_DESKTOP_INTEGRATION "Allow perfoming desktop integration during runtime" 1 "NOT SLIC3R_FHS" 0) @@ -271,6 +272,32 @@ if (SLIC3R_ASAN) endif () endif () +if (SLIC3R_UBSAN) + # Stacktrace for every report is enabled by default. It can be disabled by running PrusaSlicer with "UBSAN_OPTIONS=print_stacktrace=0". + + # Define macro SLIC3R_UBSAN to allow detection in the source code if this sanitizer is enabled. + add_compile_definitions(SLIC3R_UBSAN) + + # Clang supports much more useful checks than GCC, so when Clang is detected, another checks will be enabled. + # List of what GCC is checking: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html + # List of what Clang is checking: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set(_ubsan_flags "-fsanitize=undefined,integer") + else () + set(_ubsan_flags "-fsanitize=undefined") + endif () + + add_compile_options(${_ubsan_flags} -fno-omit-frame-pointer) + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${_ubsan_flags}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${_ubsan_flags}") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${_ubsan_flags}") + + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lubsan") + endif () +endif () + if (APPLE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=partial-availability -Werror=unguarded-availability -Werror=unguarded-availability-new") diff --git a/deps/Boost/Boost.cmake b/deps/Boost/Boost.cmake index ec8bab799c..15792d5a75 100644 --- a/deps/Boost/Boost.cmake +++ b/deps/Boost/Boost.cmake @@ -120,6 +120,12 @@ set(_build_cmd ${_build_cmd} set(_install_cmd ${_build_cmd} --prefix=${_prefix} install) +if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + # When Clang is used with enabled UndefinedBehaviorSanitizer, it produces "undefined reference to '__muloti4'" when __int128 is used. + # Because of that, UndefinedBehaviorSanitizer is disabled for those functions that use __int128. + list(APPEND _patch_command COMMAND ${PATCH_CMD} ${CMAKE_CURRENT_LIST_DIR}/Boost.patch) +endif () + ExternalProject_Add( dep_Boost URL "https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz" diff --git a/deps/Boost/Boost.patch b/deps/Boost/Boost.patch new file mode 100644 index 0000000000..8c54430b96 --- /dev/null +++ b/deps/Boost/Boost.patch @@ -0,0 +1,23 @@ +diff -u ../boost_1_75_0-orig/boost/rational.hpp ./boost/rational.hpp +--- ../boost_1_75_0-orig/boost/rational.hpp 2020-12-03 06:02:19.000000000 +0100 ++++ ./boost/rational.hpp 2022-01-27 16:02:27.993848905 +0100 +@@ -302,6 +302,9 @@ + return *this; + } + template ++ #if defined(__clang__) ++ __attribute__((no_sanitize("undefined"))) ++ #endif + BOOST_CXX14_CONSTEXPR typename boost::enable_if_c::value, rational&>::type operator*= (const T& i) + { + // Avoid overflow and preserve normalization +@@ -311,6 +314,9 @@ + return *this; + } + template ++ #if defined(__clang__) ++ __attribute__((no_sanitize("undefined"))) ++ #endif + BOOST_CXX14_CONSTEXPR typename boost::enable_if_c::value, rational&>::type operator/= (const T& i) + { + // Avoid repeated construction diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 78e3623d9f..2648fba9e2 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -843,6 +843,15 @@ extern "C" { } #endif +#if defined(SLIC3R_UBSAN) +extern "C" { + // Enable printing stacktrace by default. It can be disabled by running PrusaSlicer with "UBSAN_OPTIONS=print_stacktrace=0". + const char *__ubsan_default_options() { + return "print_stacktrace=1"; + } +} +#endif + #if defined(_MSC_VER) || defined(__MINGW32__) extern "C" { __declspec(dllexport) int __stdcall slic3r_main(int argc, wchar_t **argv) diff --git a/src/libslic3r/Int128.hpp b/src/libslic3r/Int128.hpp index 8dc9e012dd..7aeacbfcee 100644 --- a/src/libslic3r/Int128.hpp +++ b/src/libslic3r/Int128.hpp @@ -105,6 +105,11 @@ public: static inline Int128 multiply(int64_t lhs, int64_t rhs) { return Int128(__int128(lhs) * __int128(rhs)); } +#if defined(__clang__) + // When Clang is used with enabled UndefinedBehaviorSanitizer, it produces "undefined reference to '__muloti4'" when __int128 is used. + // Because of that, UndefinedBehaviorSanitizer is disabled for this function. + __attribute__((no_sanitize("undefined"))) +#endif // Evaluate signum of a 2x2 determinant. static int sign_determinant_2x2(int64_t a11, int64_t a12, int64_t a21, int64_t a22) {