|
7 | 7 | ! |
8 | 8 | #include "assert_macros.h" |
9 | 9 |
|
| 10 | +#include "assert_features.h" |
| 11 | + |
10 | 12 | module assert_subroutine_m |
11 | 13 | !! summary: Utility for runtime enforcement of logical assertions. |
12 | 14 | !! usage: error-terminate if the assertion fails: |
@@ -66,25 +68,61 @@ pure subroutine assert_error_stop_interface(stop_code_char) |
66 | 68 | #endif |
67 | 69 | logical, parameter :: enforce_assertions=USE_ASSERTIONS |
68 | 70 |
|
69 | | - interface |
70 | 71 |
|
71 | | - pure module subroutine assert(assertion, description) |
| 72 | +contains |
| 73 | + |
| 74 | + pure subroutine assert(assertion, description) |
72 | 75 | !! If assertion is .false. and enforcement is enabled (e.g. via -DASSERTIONS=1), |
73 | 76 | !! then error-terminate with a character stop code that contains the description argument if present |
74 | 77 | implicit none |
75 | 78 | logical, intent(in) :: assertion |
76 | 79 | !! Most assertions will be expressions such as i>0 |
77 | 80 | character(len=*), intent(in) :: description |
78 | 81 | !! A brief statement of what is being asserted such as "i>0" or "positive i" |
79 | | - end subroutine |
80 | 82 |
|
81 | | - pure module subroutine assert_always(assertion, description) |
| 83 | + toggle_assertions: & |
| 84 | + if (enforce_assertions) then |
| 85 | + call assert_always(assertion, description) |
| 86 | + end if toggle_assertions |
| 87 | + |
| 88 | + end subroutine |
| 89 | + |
| 90 | + pure subroutine assert_always(assertion, description) |
82 | 91 | !! Same as above but always enforces the assertion (regardless of ASSERTIONS) |
83 | 92 | implicit none |
84 | 93 | logical, intent(in) :: assertion |
85 | 94 | character(len=*), intent(in) :: description |
86 | | - end subroutine |
| 95 | + character(len=:), allocatable :: message |
| 96 | + integer me |
87 | 97 |
|
88 | | - end interface |
| 98 | + check_assertion: & |
| 99 | + if (.not. assertion) then |
| 100 | + |
| 101 | +#if ASSERT_MULTI_IMAGE |
| 102 | +# if ASSERT_PARALLEL_CALLBACKS |
| 103 | + me = assert_this_image() |
| 104 | +# else |
| 105 | + me = this_image() |
| 106 | +# endif |
| 107 | + block |
| 108 | + character(len=128) image_number |
| 109 | + write(image_number, *) me |
| 110 | + message = 'Assertion failure on image ' // trim(adjustl(image_number)) // ':' // description |
| 111 | + end block |
| 112 | +#else |
| 113 | + message = 'Assertion failure: ' // description |
| 114 | + me = 0 ! avoid a harmless warning |
| 115 | +#endif |
| 116 | + |
| 117 | +#if ASSERT_PARALLEL_CALLBACKS |
| 118 | + call assert_error_stop(message) |
| 119 | +#else |
| 120 | + error stop message, QUIET=.false. |
| 121 | +#endif |
| 122 | + |
| 123 | + end if check_assertion |
| 124 | + |
| 125 | + end subroutine |
89 | 126 |
|
90 | 127 | end module assert_subroutine_m |
| 128 | + |
0 commit comments