From 6d9d35c9851039863a0f14af498096fea2802f98 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Sat, 26 May 2018 09:44:18 +0200 Subject: [PATCH] acc: turn some assertions into exceptions * spot/misc/bitset.cc, spot/misc/bitset.hh (set, clear): Turn asserts into exceptions. * spot/twa/acc.hh (mark_t): As a consequence, the constructor is not noexcept anymore. * tests/core/acc.cc, tests/python/except.py: More tests. --- spot/misc/bitset.cc | 6 ++++++ spot/misc/bitset.hh | 17 ++++++++++++++--- spot/twa/acc.hh | 6 ++++-- tests/core/acc.cc | 8 ++++++++ tests/python/except.py | 15 ++++++++++++++- 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/spot/misc/bitset.cc b/spot/misc/bitset.cc index 97bbfef5a..632b0ded1 100644 --- a/spot/misc/bitset.cc +++ b/spot/misc/bitset.cc @@ -19,6 +19,7 @@ #include "config.h" #include +#include namespace spot { @@ -28,5 +29,10 @@ namespace spot { throw std::runtime_error("bit shift by more bits than supported"); } + + void report_bit_out_of_bounds() + { + throw std::runtime_error("bit index is out of bounds"); + } } } diff --git a/spot/misc/bitset.hh b/spot/misc/bitset.hh index 69a6ce3b9..bb1693d2b 100644 --- a/spot/misc/bitset.hh +++ b/spot/misc/bitset.hh @@ -29,11 +29,12 @@ namespace spot namespace internal { [[noreturn]] SPOT_API void report_bit_shift_too_big(); + [[noreturn]] SPOT_API void report_bit_out_of_bounds(); } #endif template - class bitset + class SPOT_API bitset { using word_t = unsigned; // the number of bits must hold on an unsigned @@ -126,13 +127,23 @@ namespace spot void set(unsigned s) { - SPOT_ASSERT(s < 8*N*sizeof(word_t)); +#if SPOT_DEBUG || defined(SWIGPYTHON) + if (SPOT_UNLIKELY(s >= 8 * N * sizeof(word_t))) + internal::report_bit_out_of_bounds(); +#else + SPOT_ASSUME(s < 8 * N * sizeof(word_t)); +#endif data[s / (8*sizeof(word_t))] |= 1U << (s % (8*sizeof(word_t))); } void clear(unsigned s) { - SPOT_ASSERT(s < 8*N*sizeof(word_t)); +#if SPOT_DEBUG || defined(SWIGPYTHON) + if (SPOT_UNLIKELY(s >= 8 * N * sizeof(word_t))) + internal::report_bit_out_of_bounds(); +#else + SPOT_ASSUME(s < 8 * N * sizeof(word_t)); +#endif data[s / (8*sizeof(word_t))] &= ~(1U << (s % (8*sizeof(word_t)))); } diff --git a/spot/twa/acc.hh b/spot/twa/acc.hh index 1062c2731..c0c1e410f 100644 --- a/spot/twa/acc.hh +++ b/spot/twa/acc.hh @@ -68,15 +68,16 @@ namespace spot public: mark_t() = default; +#ifndef SWIG template - mark_t(const iterator& begin, const iterator& end) noexcept + mark_t(const iterator& begin, const iterator& end) : mark_t(_value_t::zero()) { for (iterator i = begin; i != end; ++i) set(*i); } - mark_t(std::initializer_list vals) noexcept + mark_t(std::initializer_list vals) : mark_t(vals.begin(), vals.end()) { } @@ -93,6 +94,7 @@ namespace spot i >>= 1; } } +#endif /// \brief The maximum number of acceptance sets supported by /// this implementation. diff --git a/tests/core/acc.cc b/tests/core/acc.cc index 9ff334a01..9aa01b3a5 100644 --- a/tests/core/acc.cc +++ b/tests/core/acc.cc @@ -218,6 +218,14 @@ int main() { assert(!std::strncmp(e.what(), "Too many acceptance sets used.", 30)); } + try + { + spot::acc_cond::mark_t m{spot::acc_cond::mark_t::max_accsets()}; + } + catch (const std::runtime_error& e) + { + assert(!std::strcmp(e.what(), "bit index is out of bounds")); + } #endif return 0; diff --git a/tests/python/except.py b/tests/python/except.py index a723ad3a8..fa637334f 100644 --- a/tests/python/except.py +++ b/tests/python/except.py @@ -137,5 +137,18 @@ try: except RuntimeError as e: assert "Too many acceptance sets" in str(e) else: - print(n, m) + report_missing_exception() + +try: + m.set(n) +except RuntimeError as e: + assert "bit index is out of bounds" in str(e) +else: + report_missing_exception() + +try: + m = spot.mark_t([0,n,1]) +except RuntimeError as e: + assert "bit index is out of bounds" in str(e) +else: report_missing_exception()