1 /* Implementation of PPL assert-like macros.
2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4
5 This file is part of the Parma Polyhedra Library (PPL).
6
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23
24 #ifndef PPL_assert_hh
25 #define PPL_assert_hh 1
26
27 // The PPL_UNREACHABLE_MSG macro flags a program point as unreachable.
28 // Argument `msg__' is added to output when assertions are turned on.
29 #if defined(NDEBUG)
30 #define PPL_UNREACHABLE_MSG(msg__) Parma_Polyhedra_Library::ppl_unreachable()
31 #else
32 #define PPL_UNREACHABLE_MSG(msg__) Parma_Polyhedra_Library:: \
33 ppl_unreachable_msg(msg__, __FILE__, __LINE__, __func__)
34 #endif
35
36 // The PPL_UNREACHABLE macro flags a program point as unreachable.
37 #define PPL_UNREACHABLE PPL_UNREACHABLE_MSG("unreachable")
38
39 // The PPL_ASSERTION_FAILED macro is used to output a message after
40 // an assertion failure and then cause program termination.
41 // (It is meant to be used only when assertions are turned on.)
42 #define PPL_ASSERTION_FAILED(msg__) Parma_Polyhedra_Library:: \
43 ppl_assertion_failed(msg__, __FILE__, __LINE__, __func__)
44
45 // Helper macro PPL_ASSERT_IMPL_: do not use it directly.
46 #if defined(NDEBUG)
47 #define PPL_ASSERT_IMPL_(cond__) ((void) 0)
48 #else
49 #define PPL_STRING_(s) #s
50 #define PPL_ASSERT_IMPL_(cond__) \
51 ((cond__) ? (void) 0 : PPL_ASSERTION_FAILED(PPL_STRING_(cond__)))
52 #endif
53
54
55 // Non zero to detect use of PPL_ASSERT instead of PPL_ASSERT_HEAVY
56 // Note: flag does not affect code built with NDEBUG defined.
57 #define PPL_DEBUG_PPL_ASSERT 1
58
59 // The PPL_ASSERT macro states that Boolean condition cond__ should hold.
60 // This is meant to replace uses of C assert().
61 #if defined(NDEBUG) || (!PPL_DEBUG_PPL_ASSERT)
62 #define PPL_ASSERT(cond__) PPL_ASSERT_IMPL_(cond__)
63 #else
64 // Note: here we have assertions enabled and PPL_DEBUG_PPL_ASSERT is 1.
65 // Check if the call to PPL_ASSERT should be replaced by PPL_ASSERT_HEAVY
66 // (i.e., if the former may interfere with computational weights).
67 #define PPL_ASSERT(cond__) \
68 do { \
69 typedef Parma_Polyhedra_Library::Weightwatch_Traits W_Traits; \
70 W_Traits::Threshold old_weight__ = W_Traits::weight; \
71 PPL_ASSERT_IMPL_(cond__); \
72 PPL_ASSERT_IMPL_(old_weight__ == W_Traits::weight \
73 && ("PPL_ASSERT_HEAVY has to be used here" != 0)); \
74 } while (false)
75 #endif // !defined(NDEBUG) && PPL_DEBUG_PPL_ASSERT
76
77
78 // Macro PPL_ASSERT_HEAVY is meant to be used when the evaluation of
79 // the assertion may change computational weights (via WEIGHT_ADD).
80 #if defined(NDEBUG)
81 #define PPL_ASSERT_HEAVY(cond__) PPL_ASSERT_IMPL_(cond__)
82 #else
83 #define PPL_ASSERT_HEAVY(cond__) \
84 do { \
85 Parma_Polyhedra_Library::In_Assert guard; \
86 PPL_ASSERT_IMPL_(cond__); \
87 } while (false)
88 #endif // !defined(NDEBUG)
89
90
91 // Macro PPL_EXPECT (resp., PPL_EXPECT_HEAVY) should be used rather than
92 // PPL_ASSERT (resp., PPL_ASSERT_HEAVY) when the condition is assumed to
93 // hold but it is not under library control (typically, it depends on
94 // user provided input).
95 #define PPL_EXPECT(cond__) PPL_ASSERT(cond__)
96 #define PPL_EXPECT_HEAVY(cond__) PPL_ASSERT_HEAVY(cond__)
97
98
99 namespace Parma_Polyhedra_Library {
100
101 #if PPL_CXX_SUPPORTS_ATTRIBUTE_WEAK
102 #define PPL_WEAK_NORETURN __attribute__((weak, noreturn))
103 #else
104 #define PPL_WEAK_NORETURN __attribute__((noreturn))
105 #endif
106
107 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
108 //! Helper function causing program termination by calling \c abort.
109 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
110 void ppl_unreachable() PPL_WEAK_NORETURN;
111
112 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
113 /*! \brief
114 Helper function printing message on \c std::cerr and causing program
115 termination by calling \c abort.
116 */
117 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
118 void ppl_unreachable_msg(const char* msg,
119 const char* file, unsigned int line,
120 const char* function) PPL_WEAK_NORETURN;
121
122 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
123 /*! \brief
124 Helper function printing an assertion failure message on \c std::cerr
125 and causing program termination by calling \c abort.
126 */
127 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
128 void ppl_assertion_failed(const char* assertion_text,
129 const char* file, unsigned int line,
130 const char* function) PPL_WEAK_NORETURN;
131
132
133 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
134 /*! \brief
135 Returns \c true if and only if \p x_copy contains \p y_copy.
136
137 \note
138 This is a helper function for debugging purposes, to be used in assertions.
139 The two arguments are meant to be passed by value, i.e., <em>copied</em>,
140 so that their representations will not be affected by the containment check.
141 */
142 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
143 template <typename T>
copy_contains(T x_copy,T y_copy)144 bool copy_contains(T x_copy, T y_copy) {
145 return x_copy.contains(y_copy);
146 }
147
148 } // namespace Parma_Polyhedra_Library
149
150 #endif // !defined(PPL_assert_hh)
151