Commit 20cf43b3 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

use SPOT_ASSERT instead of assert

For #184.

* spot/graph/graph.hh, spot/kripke/kripkegraph.hh,
spot/misc/bitvect.hh, spot/misc/common.hh, spot/misc/fixpool.hh,
spot/misc/mspool.hh, spot/misc/timer.hh, spot/tl/formula.hh,
spot/twa/acc.hh, spot/twa/taatgba.hh, spot/twa/twa.hh,
spot/twa/twagraph.hh, spot/twaalgos/emptiness_stats.hh,
spot/twaalgos/mask.hh, spot/twaalgos/ndfs_result.hxx,
spot/twaalgos/sccinfo.hh, spot/twaalgos/translate.hh: Replace
assert() by SPOT_ASSERT(), or an exception, or nothing, depending
on the case.
* tests/sanity/style.test: Flag all asserts in headers.
* HACKING: Discuss assertions.
parent 9f7bf5ab
...@@ -346,6 +346,22 @@ Exporting symbols ...@@ -346,6 +346,22 @@ Exporting symbols
* Read http://www.akkadia.org/drepper/dsohowto.pdf for more * Read http://www.akkadia.org/drepper/dsohowto.pdf for more
information about how shared libraries work and why. information about how shared libraries work and why.
Assertions
----------
* There are different types of assertions. Plain assert() is OK for
invariants or post-conditions. When asserting a pre-condition,
carefully consider who the caller might be: if it can be in
user-code (either in C++ or Python), throw an exception
(std::runtime_error, std::invalid_argument, and spot::parse_error
are the three exception types catched by the Python bindings).
* Do not call assert() in public *.hh files: even if the installed
libspot has been compiled with -DNDEBUG, the *.hh files will be
recompiled by users, probably without -DNDEBUG. So use
SPOT_ASSERT() instead of assert(), this ensure asserts are only
used inside libspot for debug builds.
Comments Comments
-------- --------
...@@ -361,7 +377,8 @@ Comments ...@@ -361,7 +377,8 @@ Comments
Formating Formating
--------- ---------
* Braces are always on their own line. * Braces around instruction blocks are always on their own line.
Braces around initializers lists need not be on their own.
* Text within braces is two-space indented. * Text within braces is two-space indented.
......
...@@ -373,7 +373,7 @@ namespace spot ...@@ -373,7 +373,7 @@ namespace spot
if (src_.succ_tail == this->t_) if (src_.succ_tail == this->t_)
{ {
src_.succ_tail = prev_; src_.succ_tail = prev_;
assert(next == 0); SPOT_ASSERT(next == 0);
} }
// Erased edges have themselves as next_succ. // Erased edges have themselves as next_succ.
...@@ -678,14 +678,12 @@ namespace spot ...@@ -678,14 +678,12 @@ namespace spot
state_storage_t& state_storage_t&
state_storage(state s) state_storage(state s)
{ {
assert(s < states_.size());
return states_[s]; return states_[s];
} }
const state_storage_t& const state_storage_t&
state_storage(state s) const state_storage(state s) const
{ {
assert(s < states_.size());
return states_[s]; return states_[s];
} }
///@} ///@}
...@@ -698,14 +696,12 @@ namespace spot ...@@ -698,14 +696,12 @@ namespace spot
typename state_storage_t::data_t& typename state_storage_t::data_t&
state_data(state s) state_data(state s)
{ {
assert(s < states_.size());
return states_[s].data(); return states_[s].data();
} }
const typename state_storage_t::data_t& const typename state_storage_t::data_t&
state_data(state s) const state_data(state s) const
{ {
assert(s < states_.size());
return states_[s].data(); return states_[s].data();
} }
///@} ///@}
...@@ -718,14 +714,12 @@ namespace spot ...@@ -718,14 +714,12 @@ namespace spot
edge_storage_t& edge_storage_t&
edge_storage(edge s) edge_storage(edge s)
{ {
assert(s < edges_.size());
return edges_[s]; return edges_[s];
} }
const edge_storage_t& const edge_storage_t&
edge_storage(edge s) const edge_storage(edge s) const
{ {
assert(s < edges_.size());
return edges_[s]; return edges_[s];
} }
///@} ///@}
...@@ -738,14 +732,12 @@ namespace spot ...@@ -738,14 +732,12 @@ namespace spot
typename edge_storage_t::data_t& typename edge_storage_t::data_t&
edge_data(edge s) edge_data(edge s)
{ {
assert(s < edges_.size());
return edges_[s].data(); return edges_[s].data();
} }
const typename edge_storage_t::data_t& const typename edge_storage_t::data_t&
edge_data(edge s) const edge_data(edge s) const
{ {
assert(s < edges_.size());
return edges_[s].data(); return edges_[s].data();
} }
///@} ///@}
...@@ -759,13 +751,11 @@ namespace spot ...@@ -759,13 +751,11 @@ namespace spot
edge edge
new_edge(state src, out_state dst, Args&&... args) new_edge(state src, out_state dst, Args&&... args)
{ {
assert(src < states_.size());
edge t = edges_.size(); edge t = edges_.size();
edges_.emplace_back(dst, 0, src, std::forward<Args>(args)...); edges_.emplace_back(dst, 0, src, std::forward<Args>(args)...);
edge st = states_[src].succ_tail; edge st = states_[src].succ_tail;
assert(st < t || !st); SPOT_ASSERT(st < t || !st);
if (!st) if (!st)
states_[src].succ = t; states_[src].succ = t;
else else
...@@ -777,14 +767,14 @@ namespace spot ...@@ -777,14 +767,14 @@ namespace spot
/// Convert a storage reference into a state number /// Convert a storage reference into a state number
state index_of_state(const state_storage_t& ss) const state index_of_state(const state_storage_t& ss) const
{ {
assert(!states_.empty()); SPOT_ASSERT(!states_.empty());
return &ss - &states_.front(); return &ss - &states_.front();
} }
/// Conveart a storage reference into an edge number /// Conveart a storage reference into an edge number
edge index_of_edge(const edge_storage_t& tt) const edge index_of_edge(const edge_storage_t& tt) const
{ {
assert(!edges_.empty()); SPOT_ASSERT(!edges_.empty());
return &tt - &edges_.front(); return &tt - &edges_.front();
} }
...@@ -1012,7 +1002,7 @@ namespace spot ...@@ -1012,7 +1002,7 @@ namespace spot
/// any iteration on the successor of a state is performed. /// any iteration on the successor of a state is performed.
void rename_states_(const std::vector<unsigned>& newst) void rename_states_(const std::vector<unsigned>& newst)
{ {
assert(newst.size() == states_.size()); SPOT_ASSERT(newst.size() == states_.size());
unsigned tend = edges_.size(); unsigned tend = edges_.size();
for (unsigned t = 1; t < tend; t++) for (unsigned t = 1; t < tend; t++)
{ {
...@@ -1028,8 +1018,8 @@ namespace spot ...@@ -1028,8 +1018,8 @@ namespace spot
/// \param used_states the number of states used (after renumbering) /// \param used_states the number of states used (after renumbering)
void defrag_states(std::vector<unsigned>&& newst, unsigned used_states) void defrag_states(std::vector<unsigned>&& newst, unsigned used_states)
{ {
assert(newst.size() == states_.size()); SPOT_ASSERT(newst.size() == states_.size());
assert(used_states > 0); SPOT_ASSERT(used_states > 0);
//std::cerr << "\nbefore defrag\n"; //std::cerr << "\nbefore defrag\n";
//dump_storage(std::cerr); //dump_storage(std::cerr);
...@@ -1080,7 +1070,7 @@ namespace spot ...@@ -1080,7 +1070,7 @@ namespace spot
tr.next_succ = newidx[tr.next_succ]; tr.next_succ = newidx[tr.next_succ];
tr.dst = newst[tr.dst]; tr.dst = newst[tr.dst];
tr.src = newst[tr.src]; tr.src = newst[tr.src];
assert(tr.dst != -1U); SPOT_ASSERT(tr.dst != -1U);
} }
// Adjust succ and succ_tails pointers in all states. // Adjust succ and succ_tails pointers in all states.
......
...@@ -42,7 +42,7 @@ namespace spot ...@@ -42,7 +42,7 @@ namespace spot
virtual int compare(const spot::state* other) const override virtual int compare(const spot::state* other) const override
{ {
auto o = down_cast<const kripke_graph_state*>(other); auto o = down_cast<const kripke_graph_state*>(other);
assert(o); SPOT_ASSERT(o);
// Do not simply return "other - this", it might not fit in an int. // Do not simply return "other - this", it might not fit in an int.
if (o < this) if (o < this)
...@@ -129,7 +129,7 @@ namespace spot ...@@ -129,7 +129,7 @@ namespace spot
virtual kripke_graph_state* dst() const override virtual kripke_graph_state* dst() const override
{ {
assert(!done()); SPOT_ASSERT(!done());
return const_cast<kripke_graph_state*> return const_cast<kripke_graph_state*>
(&g_->state_data(g_->edge_storage(p_).dst)); (&g_->state_data(g_->edge_storage(p_).dst));
} }
...@@ -169,7 +169,9 @@ namespace spot ...@@ -169,7 +169,9 @@ namespace spot
void set_init_state(graph_t::state s) void set_init_state(graph_t::state s)
{ {
assert(s < num_states()); if (SPOT_UNLIKELY(s >= num_states()))
throw std::invalid_argument
("set_init_state() called with nonexisiting state");
init_number_ = s; init_number_ = s;
} }
...@@ -193,8 +195,8 @@ namespace spot ...@@ -193,8 +195,8 @@ namespace spot
succ_iter(const spot::state* st) const override succ_iter(const spot::state* st) const override
{ {
auto s = down_cast<const typename graph_t::state_storage_t*>(st); auto s = down_cast<const typename graph_t::state_storage_t*>(st);
assert(s); SPOT_ASSERT(s);
assert(!s->succ || g_.is_valid_edge(s->succ)); SPOT_ASSERT(!s->succ || g_.is_valid_edge(s->succ));
if (this->iter_cache_) if (this->iter_cache_)
{ {
...@@ -212,7 +214,7 @@ namespace spot ...@@ -212,7 +214,7 @@ namespace spot
state_number(const state* st) const state_number(const state* st) const
{ {
auto s = down_cast<const typename graph_t::state_storage_t*>(st); auto s = down_cast<const typename graph_t::state_storage_t*>(st);
assert(s); SPOT_ASSERT(s);
return s - &g_.state_storage(0); return s - &g_.state_storage(0);
} }
......
...@@ -191,7 +191,7 @@ namespace spot ...@@ -191,7 +191,7 @@ namespace spot
bool get(size_t pos) const bool get(size_t pos) const
{ {
assert(pos < size_); SPOT_ASSERT(pos < size_);
const size_t bpb = 8 * sizeof(block_t); const size_t bpb = 8 * sizeof(block_t);
return storage_[pos / bpb] & (1UL << (pos % bpb)); return storage_[pos / bpb] & (1UL << (pos % bpb));
} }
...@@ -248,21 +248,21 @@ namespace spot ...@@ -248,21 +248,21 @@ namespace spot
void set(size_t pos) void set(size_t pos)
{ {
assert(pos < size_); SPOT_ASSERT(pos < size_);
const size_t bpb = 8 * sizeof(block_t); const size_t bpb = 8 * sizeof(block_t);
storage_[pos / bpb] |= 1UL << (pos % bpb); storage_[pos / bpb] |= 1UL << (pos % bpb);
} }
void clear(size_t pos) void clear(size_t pos)
{ {
assert(pos < size_); SPOT_ASSERT(pos < size_);
const size_t bpb = 8 * sizeof(block_t); const size_t bpb = 8 * sizeof(block_t);
storage_[pos / bpb] &= ~(1UL << (pos % bpb)); storage_[pos / bpb] &= ~(1UL << (pos % bpb));
} }
void flip(size_t pos) void flip(size_t pos)
{ {
assert(pos < size_); SPOT_ASSERT(pos < size_);
const size_t bpb = 8 * sizeof(block_t); const size_t bpb = 8 * sizeof(block_t);
storage_[pos / bpb] ^= (1UL << (pos % bpb)); storage_[pos / bpb] ^= (1UL << (pos % bpb));
} }
...@@ -270,7 +270,7 @@ namespace spot ...@@ -270,7 +270,7 @@ namespace spot
bitvect& operator|=(const bitvect& other) bitvect& operator|=(const bitvect& other)
{ {
assert(other.size_ <= size_); SPOT_ASSERT(other.size_ <= size_);
unsigned m = std::min(other.block_count_, block_count_); unsigned m = std::min(other.block_count_, block_count_);
for (size_t i = 0; i < m; ++i) for (size_t i = 0; i < m; ++i)
storage_[i] |= other.storage_[i]; storage_[i] |= other.storage_[i];
...@@ -279,7 +279,7 @@ namespace spot ...@@ -279,7 +279,7 @@ namespace spot
bitvect& operator&=(const bitvect& other) bitvect& operator&=(const bitvect& other)
{ {
assert(other.size_ <= size_); SPOT_ASSERT(other.size_ <= size_);
unsigned m = std::min(other.block_count_, block_count_); unsigned m = std::min(other.block_count_, block_count_);
for (size_t i = 0; i < m; ++i) for (size_t i = 0; i < m; ++i)
storage_[i] &= other.storage_[i]; storage_[i] &= other.storage_[i];
...@@ -288,7 +288,7 @@ namespace spot ...@@ -288,7 +288,7 @@ namespace spot
bitvect& operator^=(const bitvect& other) bitvect& operator^=(const bitvect& other)
{ {
assert(other.size_ <= size_); SPOT_ASSERT(other.size_ <= size_);
unsigned m = std::min(other.block_count_, block_count_); unsigned m = std::min(other.block_count_, block_count_);
for (size_t i = 0; i < m; ++i) for (size_t i = 0; i < m; ++i)
storage_[i] ^= other.storage_[i]; storage_[i] ^= other.storage_[i];
...@@ -297,7 +297,7 @@ namespace spot ...@@ -297,7 +297,7 @@ namespace spot
bitvect& operator-=(const bitvect& other) bitvect& operator-=(const bitvect& other)
{ {
assert(other.block_count_ <= block_count_); SPOT_ASSERT(other.block_count_ <= block_count_);
for (size_t i = 0; i < other.block_count_; ++i) for (size_t i = 0; i < other.block_count_; ++i)
storage_[i] &= ~other.storage_[i]; storage_[i] &= ~other.storage_[i];
return *this; return *this;
...@@ -305,7 +305,7 @@ namespace spot ...@@ -305,7 +305,7 @@ namespace spot
bool is_subset_of(const bitvect& other) const bool is_subset_of(const bitvect& other) const
{ {
assert(other.block_count_ >= block_count_); SPOT_ASSERT(other.block_count_ >= block_count_);
size_t i; size_t i;
const size_t bpb = 8 * sizeof(bitvect::block_t); const size_t bpb = 8 * sizeof(bitvect::block_t);
...@@ -391,8 +391,8 @@ namespace spot ...@@ -391,8 +391,8 @@ namespace spot
// to \a end (excluded). // to \a end (excluded).
bitvect* extract_range(size_t begin, size_t end) bitvect* extract_range(size_t begin, size_t end)
{ {
assert(begin <= end); SPOT_ASSERT(begin <= end);
assert(end <= size()); SPOT_ASSERT(end <= size());
size_t count = end - begin; size_t count = end - begin;
bitvect* res = make_bitvect(count); bitvect* res = make_bitvect(count);
res->make_empty(); res->make_empty();
...@@ -423,13 +423,13 @@ namespace spot ...@@ -423,13 +423,13 @@ namespace spot
++indexb; ++indexb;
res->push_back(storage_[indexb], bpb); res->push_back(storage_[indexb], bpb);
count -= bpb; count -= bpb;
assert(indexb != indexe || count == 0); SPOT_ASSERT(indexb != indexe || count == 0);
} }
if (count > 0) if (count > 0)
{ {
++indexb; ++indexb;
assert(indexb == indexe); SPOT_ASSERT(indexb == indexe);
assert(count == end % bpb); SPOT_ASSERT(count == end % bpb);
res->push_back(storage_[indexb], count); res->push_back(storage_[indexb], count);
} }
} }
...@@ -495,7 +495,7 @@ namespace spot ...@@ -495,7 +495,7 @@ namespace spot
/// Return the bit-vector at \a index. /// Return the bit-vector at \a index.
bitvect& at(const size_t index) bitvect& at(const size_t index)
{ {
assert(index < size_); SPOT_ASSERT(index < size_);
return *reinterpret_cast<bitvect*>(storage() + index * bvsize_); return *reinterpret_cast<bitvect*>(storage() + index * bvsize_);
} }
...@@ -510,7 +510,7 @@ namespace spot ...@@ -510,7 +510,7 @@ namespace spot
/// Return the bit-vector at \a index. /// Return the bit-vector at \a index.
const bitvect& at(const size_t index) const const bitvect& at(const size_t index) const
{ {
assert(index < size_); SPOT_ASSERT(index < size_);
return *reinterpret_cast<const bitvect*>(storage() + index * bvsize_); return *reinterpret_cast<const bitvect*>(storage() + index * bvsize_);
} }
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et // Copyright (C) 2013, 2014, 2015, 2016 Laboratoire de Recherche et
// Développement de l'Epita (LRDE). // Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
...@@ -58,6 +58,18 @@ ...@@ -58,6 +58,18 @@
#define SPOT_DLL #define SPOT_DLL
#endif #endif
// We should not call assert() in headers. For the rare cases where
// we do really want to call assert(), use spot_assert__ instead.
// Else use SPOT_ASSERT so the assert() are removed from user's
// builds.
#define spot_assert__ assert
#if defined(SPOT_BUILD) or defined(SPOT_DEBUG)
#define SPOT_ASSERT(x) spot_assert__(x)
#else
#define SPOT_ASSERT(x) while (0)
#endif
// SPOT_API is used for the public API symbols. It either DLL imports // SPOT_API is used for the public API symbols. It either DLL imports
// or DLL exports (or does nothing for static build) SPOT_LOCAL is // or DLL exports (or does nothing for static build) SPOT_LOCAL is
// used for non-api symbols that may occur in header files. // used for non-api symbols that may occur in header files.
...@@ -93,9 +105,9 @@ ...@@ -93,9 +105,9 @@
// The extra parentheses in assert() is so that this // The extra parentheses in assert() is so that this
// pattern is not caught by the style checker. // pattern is not caught by the style checker.
#define SPOT_UNREACHABLE() do { \ #define SPOT_UNREACHABLE() do { \
assert(!("unreachable code reached")); \ SPOT_ASSERT(!("unreachable code reached")); \
SPOT_UNREACHABLE_BUILTIN(); \ SPOT_UNREACHABLE_BUILTIN(); \
} while (0) } while (0)
#define SPOT_UNIMPLEMENTED() throw std::runtime_error("unimplemented"); #define SPOT_UNIMPLEMENTED() throw std::runtime_error("unimplemented");
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2011, 2015 Laboratoire de Recherche et Développement // Copyright (C) 2011, 2015, 2016 Laboratoire de Recherche et
// de l'Epita (LRDE) // Développement de l'Epita (LRDE)
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
...@@ -95,7 +95,7 @@ namespace spot ...@@ -95,7 +95,7 @@ namespace spot
void void
deallocate (const void* ptr) deallocate (const void* ptr)
{ {
assert(ptr); SPOT_ASSERT(ptr);
block_* b = reinterpret_cast<block_*>(const_cast<void*>(ptr)); block_* b = reinterpret_cast<block_*>(const_cast<void*>(ptr));
b->next = freelist_; b->next = freelist_;
freelist_ = b; freelist_ = b;
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2011, 2013, 2015 Laboratoire de Recherche et Developpement // Copyright (C) 2011, 2013, 2015, 2016 Laboratoire de Recherche et
// de l'Epita (LRDE) // Developpement de l'Epita (LRDE)
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
...@@ -107,7 +107,7 @@ namespace spot ...@@ -107,7 +107,7 @@ namespace spot
void void
deallocate (const void* ptr, size_t size) deallocate (const void* ptr, size_t size)
{ {
assert(ptr); SPOT_ASSERT(ptr);
size = fixsize(size); size = fixsize(size);
block_* b = reinterpret_cast<block_*>(const_cast<void*>(ptr)); block_* b = reinterpret_cast<block_*>(const_cast<void*>(ptr));
block_*& f = freelist_[size]; block_*& f = freelist_[size];
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2009, 2011, 2012, 2013, 2014, 2015 Laboratoire de // Copyright (C) 2009, 2011, 2012, 2013, 2014, 2015, 2016 Laboratoire de
// Recherche et Développement de l'Epita (LRDE). // Recherche et Développement de l'Epita (LRDE).
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
...@@ -91,7 +91,7 @@ namespace spot ...@@ -91,7 +91,7 @@ namespace spot
void void
start() start()
{ {
assert(!running); SPOT_ASSERT(!running);
running = true; running = true;
#ifdef SPOT_HAVE_TIMES #ifdef SPOT_HAVE_TIMES
struct tms tmp;