diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d2e6a9f..29a73670 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ option( ENABLE_UNIT_TESTS "Enable Catch unit tests") option( ENABLE_CPP_CORE_GUIDELINES_CHECK "Enable cpp core guideline checks on ngcore" OFF) option( USE_SPDLOG "Enable spd log logging" ON) option( DEBUG_LOG "Enable more debug output (may increase computation time) - only works with USE_SPDLOG=ON" OFF) +option( CHECK_RANGE "Check array range access, automatically enabled if built in debug mode" OFF) option( USE_SUPERBUILD "use ccache" ON) diff --git a/cmake/SuperBuild.cmake b/cmake/SuperBuild.cmake index 6e7fabd7..646de088 100644 --- a/cmake/SuperBuild.cmake +++ b/cmake/SuperBuild.cmake @@ -144,6 +144,7 @@ set_vars( NETGEN_CMAKE_ARGS ENABLE_CPP_CORE_GUIDELINES_CHECK USE_SPDLOG DEBUG_LOG + CHECK_RANGE ) # propagate all variables set on the command line using cmake -DFOO=BAR diff --git a/libsrc/core/CMakeLists.txt b/libsrc/core/CMakeLists.txt index 8f6cb5ad..805808d5 100644 --- a/libsrc/core/CMakeLists.txt +++ b/libsrc/core/CMakeLists.txt @@ -1,11 +1,17 @@ -add_library(ngcore SHARED archive.cpp logging.cpp) +add_library(ngcore SHARED archive.cpp logging.cpp flags.cpp) target_compile_definitions(ngcore PRIVATE NGCORE_EXPORTS) if(NOT WIN32) target_compile_options(ngcore PRIVATE -fvisibility=hidden) endif(NOT WIN32) +target_compile_definitions(ngcore PUBLIC $<$:NETGEN_ENABLE_CHECK_RANGE>) + +if(CHECK_RANGE) + target_compile_definitions(ngcore PUBLIC NETGEN_ENABLE_CHECK_RANGE) +endif(CHECK_RANGE) + if(USE_SPDLOG) include_directories(${SPDLOG_INCLUDE_DIR}) install(DIRECTORY ${SPDLOG_INCLUDE_DIR} diff --git a/libsrc/core/exception.hpp b/libsrc/core/exception.hpp index 248a180f..35359e65 100644 --- a/libsrc/core/exception.hpp +++ b/libsrc/core/exception.hpp @@ -51,13 +51,21 @@ namespace ngcore { public: /// where it occurs, index, minimal and maximal indices - RangeException (const std::string & where, + RangeException (const std::string & where, int ind, int imin, int imax) : Exception("") { std::stringstream str; str << where << ": index " << ind << " out of range [" << imin << "," << imax << "]\n"; Append (str.str()); } + + template + RangeException(const std::string& where, const T& value) + { + std::stringstream str; + str << where << " called with wrong value " << value << "\n"; + Append(str.str()); + } }; // Exception used if no simd implementation is available to fall back to standard evaluation @@ -65,4 +73,18 @@ namespace ngcore { public: using Exception::Exception; }; } // namespace ngcore +#define NETGEN_CORE_NGEXEPTION_STR_HELPER(x) #x +#define NETGEN_CORE_NGEXEPTION_STR(x) NETGEN_CORE_NGEXEPTION_STR_HELPER(x) + +// Convenience macro to append file name and line of exception origin to the string +#define NG_EXCEPTION(s) ngcore::Exception(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t"+std::string(s)) + +#ifdef NETGEN_ENABLE_CHECK_RANGE +#define NETGEN_CHECK_RANGE(value, min, max) \ + { if ((value)<(min) || (value)>=(max)) \ + throw ngcore::RangeException(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", (value), (min), (max)); } +#else // NETGEN_ENABLE_CHECK_RANGE +#define NETGEN_CHECK_RANGE(value, min, max) +#endif // NETGEN_ENABLE_CHECK_RANGE + #endif // NETGEN_CORE_EXCEPTION_HPP