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.
This commit is contained in:
Alexandre Duret-Lutz 2018-05-26 09:44:18 +02:00
parent be0997c97a
commit 6d9d35c985
5 changed files with 46 additions and 6 deletions

View file

@ -19,6 +19,7 @@
#include "config.h"
#include <spot/misc/bitset.hh>
#include <stdexcept>
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");
}
}
}

View file

@ -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<size_t N>
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))));
}

View file

@ -68,15 +68,16 @@ namespace spot
public:
mark_t() = default;
#ifndef SWIG
template<class iterator>
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<unsigned> vals) noexcept
mark_t(std::initializer_list<unsigned> 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.

View file

@ -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;

View file

@ -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()