SpECTRE Documentation Coverage Report
Current view: top level - Utilities/ErrorHandling - Error.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 100.0 % 4 4
Test Date: 2026-10-22 17:29:42
Legend: Lines:     hit not hit

            Line data    Source code
       1            1 : // Distributed under the MIT License.
       2              : // See LICENSE.txt for details.
       3              : 
       4              : /// \file
       5              : /// Defines macro ERROR.
       6              : 
       7              : #pragma once
       8              : 
       9              : #include <iomanip>
      10              : #include <string>
      11              : 
      12              : #include "Utilities/ErrorHandling/AbortWithErrorMessage.hpp"
      13              : #include "Utilities/ErrorHandling/Breakpoint.hpp"
      14              : #include "Utilities/ErrorHandling/Exceptions.hpp"
      15              : #include "Utilities/ErrorHandling/FloatingPointExceptions.hpp"
      16              : #include "Utilities/ForceInline.hpp"
      17              : #include "Utilities/Literals.hpp"
      18              : #include "Utilities/MakeString.hpp"
      19              : #include "Utilities/System/Abort.hpp"
      20              : 
      21              : namespace Error_detail {
      22              : // You can't use ScopedFpeState (a non-literal type) in a constexpr
      23              : // function, but you can call another function that uses it.
      24              : template <typename ExceptionTypeToThrow, typename F>
      25              : [[noreturn]] SPECTRE_ALWAYS_INLINE void abort_without_fpes(
      26              :     const char* file, const int line, const char* const pretty_function,
      27              :     F&& message) {
      28              :   const ScopedFpeState disable_fpes(false);
      29              :   abort_with_error_message<ExceptionTypeToThrow>(file, line, pretty_function,
      30              :                                                  message());
      31              : }
      32              : }  // namespace Error_detail
      33              : 
      34              : /*!
      35              :  * \ingroup ErrorHandlingGroup
      36              :  * \brief prints an error message to the standard error stream and aborts the
      37              :  * program.
      38              :  *
      39              :  * ERROR should not be used for coding errors, but instead for user errors
      40              :  * or failure modes of numerical algorithms. An acceptable use for error is also
      41              :  * in the default case of a switch statement.
      42              :  *
      43              :  * \details
      44              :  * The implementation is specialized so that in compile time contexts, a short
      45              :  * error message will be thrown, but in runtime contexts, a more verbose error
      46              :  * will be printed. This specialization of throwing a short error at compile
      47              :  * time greatly reduces the compile time and memory consumption during debug
      48              :  * builds of deep and heavily inlined `TensorExpression` tree traversals.
      49              :  *
      50              :  * To accomplish this, `__builtin_is_constant_evaluated()` is used directly
      51              :  * instead of calling a wrapper function because calling a wrapper was found to
      52              :  * slightly increase the compile time and memory usage of large
      53              :  * `TensorExpression`s when compiling in debug mode.
      54              :  *
      55              :  * \param m an arbitrary output stream.
      56              :  */
      57              : // isocpp.org recommends using an `if (true)` instead of a `do
      58              : // while(false)` for macros because the latter can mess with inlining
      59              : // in some (old?) compilers:
      60              : // https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-multi-stmts
      61              : // https://isocpp.org/wiki/faq/misc-technical-issues#macros-with-if
      62              : // However, Intel's reachability analyzer (as of version 16.0.3
      63              : // 20160415) can't figure out that the else branch and everything
      64              : // after it is unreachable, causing warnings (and possibly suboptimal
      65              : // code generation).
      66              : #ifdef __CUDA_ARCH__
      67              : #if defined(__clang__) && defined(__CUDA__)
      68              : #define ERROR(m)                                              \
      69              :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
      70              :   __builtin_trap();
      71              : #else
      72              : #define ERROR(m)                                              \
      73              :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
      74              :   __trap();
      75              : #endif
      76              : #else
      77            1 : #define ERROR(m)                                                             \
      78              :   do {                                                                       \
      79              :     if (__builtin_is_constant_evaluated()) {                                 \
      80              :       throw std::runtime_error("Failed");                                    \
      81              :     } else {                                                                 \
      82              :       Error_detail::abort_without_fpes<SpectreError>(                        \
      83              :           __FILE__, __LINE__, static_cast<const char*>(__PRETTY_FUNCTION__), \
      84              :           [&]() -> std::string {                                             \
      85              :             return MakeString{} << std::setprecision(18) << std::scientific  \
      86              :                                 << m;                                        \
      87              :           });                                                                \
      88              :     }                                                                        \
      89              :   } while (false)
      90              : #endif
      91              : 
      92              : /*!
      93              :  * \ingroup ErrorHandlingGroup
      94              :  * \brief Same as ERROR but will throw `EXCEPTION_TYPE` instead of
      95              :  * `SpectreError`.
      96              :  *
      97              :  * \note Any exception types used must have an associated explicit
      98              :  * instantiation in `Utilities/ErrorHandling/AbortWithErrorMessage.cpp`
      99              :  */
     100              : #ifdef __CUDA_ARCH__
     101              : #if defined(__clang__) && defined(__CUDA__)
     102              : #define ERROR_AS(m, EXCEPTION_TYPE)                           \
     103              :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
     104              :   __builtin_trap();
     105              : #else
     106              : #define ERROR_AS(m, EXCEPTION_TYPE)                           \
     107              :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
     108              :   __trap();
     109              : #endif
     110              : #else
     111            1 : #define ERROR_AS(m, EXCEPTION_TYPE)                                          \
     112              :   do {                                                                       \
     113              :     if (__builtin_is_constant_evaluated()) {                                 \
     114              :       throw std::runtime_error("Failed");                                    \
     115              :     } else {                                                                 \
     116              :       Error_detail::abort_without_fpes<EXCEPTION_TYPE>(                      \
     117              :           __FILE__, __LINE__, static_cast<const char*>(__PRETTY_FUNCTION__), \
     118              :           [&]() -> std::string {                                             \
     119              :             return MakeString{} << std::setprecision(18) << std::scientific  \
     120              :                                 << m;                                        \
     121              :           });                                                                \
     122              :     }                                                                        \
     123              :   } while (false)
     124              : #endif
     125              : 
     126              : /*!
     127              :  * \ingroup ErrorHandlingGroup
     128              :  * \brief Same as ERROR but does not print a backtrace. Intended to be used for
     129              :  * user errors, such as incorrect values in an input file.
     130              :  */
     131              : #ifdef __CUDA_ARCH__
     132              : #if defined(__clang__) && defined(__CUDA__)
     133              : #define ERROR_NO_TRACE(m)                                     \
     134              :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
     135              :   __builtin_trap();
     136              : #else
     137              : #define ERROR_NO_TRACE(m)                                     \
     138              :   printf("Error in file %s on line %d.", __FILE__, __LINE__); \
     139              :   __trap();
     140              : #endif
     141              : #else
     142            1 : #define ERROR_NO_TRACE(m)                                                    \
     143              :   do {                                                                       \
     144              :     if (__builtin_is_constant_evaluated()) {                                 \
     145              :       throw std::runtime_error("Failed");                                    \
     146              :     } else {                                                                 \
     147              :       const ScopedFpeState disable_fpes_ERROR(false);                        \
     148              :       abort_with_error_message_no_trace(                                     \
     149              :           __FILE__, __LINE__, static_cast<const char*>(__PRETTY_FUNCTION__), \
     150              :           MakeString{} << std::setprecision(18) << std::scientific << m);    \
     151              :     }                                                                        \
     152              :   } while (false)
     153              : #endif
        

Generated by: LCOV version 2.0-1