ROSE  0.11.25.0
RoseAsserts.h
1 #ifndef ROSE_ASSERTS_H
2 #define ROSE_ASSERTS_H
3 
4 /*------------------------------------------------------------------------------
5 |
6 | Note that much of this file was extracted from src/util/processSupport.h
7 | JFR 2020-Jun-05
8 |
9 +-----------------------------------------------------------------------------*/
10 
11 #include "rosedll.h"
12 #include <Sawyer/Assert.h>
13 
14 /*{---------------------------------------------------------------------------*/
15 #if 0
16 /* I think that this may already be used. */
17 /* DQ (4/23/2016): Added to include ROSE_ASSERTION_EXIT and related macro definitions. */
18 # include "Diagnostics.h"
19 
20 /* Check that ROSE_ASSERTION_BEHAVIOR is defined. */
21 # ifndef ROSE_ASSERTION_BEHAVIOR
22 
23 # ifndef ROSE_ASSERTION_EXIT
24 # endif
25 
26 /* This determines how failed assertions should behave, we want it to be defined as: */
27 # define ROSE_ASSERTION_BEHAVIOR ROSE_ASSERTION_EXIT
28 
29 /* # error "We want to have ROSE_ASSERTION_BEHAVIOR be defined" */
30 # endif
31 #endif
32 /*}---------------------------------------------------------------------------*/
33 
34 /*{-----------------------------------------------------------------------------
35 |
36 | Logic assertion checking.
37 |
38 | ROSE_ASSERT can be used to check assertions in program logic; it should not be used to report errors caused by users. This
39 | macro is used in approximately 36,000 places in the library, tutorial, tests, and projects and is sometimes used
40 | (incorrectly) to report user errors. Therefore it is impracticable to inspect all uses, and we must continue to ensure that
41 | all calls to ROSE_ASSERT are checked at runtime regardless of whether NDEBUG is defined.
42 |
43 | New code should use Sawyer's ASSERT_* macros to check logic assertions because:
44 | + It has two-argument versions where the second argument is the string describing what's wrong in more user-friendly
45 | terms. E.g. ASSERT_forbid2(s.empty(), "symbol name cannot be the empty string").
46 | + The name encodes whether the macro is disabled when NDEBUG is defined. The "always" versions are never disabled, nor
47 | are the macros ASSERT_not_implemented, ASSERT_not_reachable, TODO, and FIXME. E.g., ASSERT_always_require(...).
48 | + Failure behavior is configurable via Rose::Diagnostics API, frontend() command-line, or autotools/cmake. E.g.,
49 | a failing assertion can abort, exit with non-zero status, or throw a Rose::Diagnostics::FailedAssertion exception.
50 | + Output from failed assertions is easier to read because it's split across multiple lines. On ANSI terminals it will
51 | show up in bright red.
52 |
53 | Additional documentation can be found here:
54 | + Sawyer ASSERT_* macros (https://hoosierfocus.com/~matzke/Sawyer/namespaceSawyer_1_1Assert.html)
55 | + Rose::Diagnostics (http://rosecompiler.org/ROSE_HTML_Reference/namespacerose_1_1Diagnostics.html)
56 |
57 +-----------------------------------------------------------------------------*/
58 
59 #ifndef ROSE_ASSERT
60  #if _MSC_VER
61  #include <assert.h>
62  #define ROSE_ASSERT assert
63  #elif defined(ROSE_ASSERTION_BEHAVIOR)
64  /* Use Sawyer ASSERT_require because it supports different behaviors (abort, exit, or throw) based on ROSE
65  | configuration and overridden at runtime by frontend() command-line switches or the Rose::Diagnostics API. However,
66  | since "ROSE_ASSERT(false)" and equivalents are used so often for "should not get here", we must ensure that
67  | ROSE_ASSERT is checked regardless of whether NDEBUG is defined (thus the "_always_" version). Also, the Sawyer
68  | ASSERT_always_* macros evaluate their arguments exactly once. New code should use ASSERT_not_implemented,
69  | ASSERT_not_reachable, TODO, or FIXME for "should not get here".
70  */
71  #define ROSE_ASSERT ASSERT_always_require
72  #elif !defined(NDEBUG)
73  /* This is the original pre-Sawyer version when NDEBUG is not defined.*/
74  #define ROSE_ASSERT assert
75  #else
76  /* This is the original pre-Sawyer version when NDEBUG is defined. It came with this comment: We use "assert(false)"
77  | equivalents so often for "should not get here", but we don't want nontrivial side effects in asserts to be run when
78  | assert is disabled.
79  */
80  #define ROSE_ASSERT(exp) do {if (__builtin_constant_p(exp)) {if (exp) {} else (std::abort)();}} while (0)
81  #endif
82 #endif
83 
84 /*}---------------------------------------------------------------------------*/
85 
86 #endif
87