Skip to content

Commit

Permalink
annotate handle_error with [[noreturn]]
Browse files Browse the repository at this point in the history
  • Loading branch information
biojppm committed Jun 22, 2024
1 parent 303bd98 commit 3af19e7
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 74 deletions.
3 changes: 2 additions & 1 deletion changelog/current.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

- Add `bool from_chars(csubstr s, fmt::overflow_checked_<T> *wrapper)`. There was already is a function receiving `&wrapper`, but `*wrapper` was missing for use with generic code.
- Annotate `c4::handle_error()` with `[[noreturn]]` ([PR#137](https://github.com/biojppm/c4core/pull/137))
- Update fast_float to v6.1.1 ([PR#136](https://github.com/biojppm/c4core/pull/136))
- Add `bool from_chars(csubstr s, fmt::overflow_checked_<T> *wrapper)`. There was already is a function receiving `&wrapper`, but `*wrapper` was missing for use with generic code.
26 changes: 13 additions & 13 deletions src/c4/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,44 +102,44 @@ void handle_error(srcloc where, const char *fmt, ...)
{
if(s_error_callback)
{
s_error_callback(buf, msglen/*ss.c_strp(), ss.tellp()*/);
s_error_callback(buf, msglen);
}
}

if(s_error_flags & ON_ERROR_ABORT)
{
abort();
}

if(s_error_flags & ON_ERROR_THROW)
{
#if defined(C4_EXCEPTIONS_ENABLED) && defined(C4_ERROR_THROWS_EXCEPTION)
throw std::runtime_error(buf);
#else
abort();
#endif
}

if(s_error_flags & ON_ERROR_ABORT)

Check warning on line 116 in src/c4/error.cpp

View check run for this annotation

Codecov / codecov/patch

src/c4/error.cpp#L116

Added line #L116 was not covered by tests
{
abort();

Check warning on line 118 in src/c4/error.cpp

View check run for this annotation

Codecov / codecov/patch

src/c4/error.cpp#L118

Added line #L118 was not covered by tests
}

abort(); // abort anyway, in case nothing was set

Check warning on line 121 in src/c4/error.cpp

View check run for this annotation

Codecov / codecov/patch

src/c4/error.cpp#L121

Added line #L121 was not covered by tests
C4_UNREACHABLE_AFTER_ERR();
}

//-----------------------------------------------------------------------------

void handle_warning(srcloc where, const char *fmt, ...)
{
va_list args;
char buf[1024]; //sstream<c4::string> ss;
char buf[1024];
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
C4_LOGF_WARN("\n");
#if defined(C4_ERROR_SHOWS_FILELINE) && defined(C4_ERROR_SHOWS_FUNC)
C4_LOGF_WARN("%s:%d: WARNING: %s\n", where.file, where.line, buf/*ss.c_strp()*/);
C4_LOGF_WARN("%s:%d: WARNING: %s\n", where.file, where.line, buf);
C4_LOGF_WARN("%s:%d: WARNING: here: %s\n", where.file, where.line, where.func);
#elif defined(C4_ERROR_SHOWS_FILELINE)
C4_LOGF_WARN("%s:%d: WARNING: %s\n", where.file, where.line, buf/*ss.c_strp()*/);
C4_LOGF_WARN("%s:%d: WARNING: %s\n", where.file, where.line, buf);

Check warning on line 139 in src/c4/error.cpp

View check run for this annotation

Codecov / codecov/patch

src/c4/error.cpp#L139

Added line #L139 was not covered by tests
#elif ! defined(C4_ERROR_SHOWS_FUNC)
C4_LOGF_WARN("WARNING: %s\n", buf/*ss.c_strp()*/);
C4_LOGF_WARN("WARNING: %s\n", buf);
#endif
//c4::log.flush();
}

//-----------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/c4/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ struct ScopedErrorSettings
/** source location */
struct srcloc;

C4CORE_EXPORT void handle_error(srcloc s, const char *fmt, ...);
C4CORE_EXPORT [[noreturn]] void handle_error(srcloc s, const char *fmt, ...);
C4CORE_EXPORT void handle_warning(srcloc s, const char *fmt, ...);


Expand Down
2 changes: 2 additions & 0 deletions test/c4/libtest/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
namespace c4 {

size_t TestErrorOccurs::num_errors = 0;
std::jmp_buf TestErrorOccurs::s_jmp_env_expect_error = {};
std::string TestErrorOccurs::s_jmp_msg;

} // namespace c4
41 changes: 28 additions & 13 deletions test/c4/test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#endif
#include <cstdio>
#include <iostream>
#include <csetjmp>

// FIXME - these are just dumb placeholders
#define C4_LOGF_ERR(...) fprintf(stderr, __VA_ARGS__)
Expand Down Expand Up @@ -89,36 +90,50 @@ inline std::ostream& operator<< (std::ostream& stream, c4::basic_substring<C> s)
return stream;
}


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/** RAII class that tests whether an error occurs inside a scope. */
struct TestErrorOccurs
{
TestErrorOccurs(size_t num_expected_errors = 1)
:
expected_errors(num_expected_errors),
tmp_settings(c4::ON_ERROR_CALLBACK, &TestErrorOccurs::error_callback)
static void error_callback(const char* msg, size_t msg_size)
{
num_errors = 0;
++num_errors;
s_jmp_msg.assign(msg, msg_size);
std::longjmp(s_jmp_env_expect_error, 37);
C4_UNREACHABLE();
}
~TestErrorOccurs()

template<class Fn>
TestErrorOccurs(Fn &&fn, const char *expected_msg=nullptr)
:
tmp_settings(c4::ON_ERROR_CALLBACK, &TestErrorOccurs::error_callback)
{
CHECK_EQ(num_errors, expected_errors);
num_errors = 0;
switch(setjmp(s_jmp_env_expect_error))
{
case 0:
fn();
break;
case 37:
// got expected error from call to fn()
if(expected_msg)
CHECK_EQ(s_jmp_msg, expected_msg);
break;
}
CHECK_EQ(num_errors, 1);
}

size_t expected_errors;
static size_t num_errors;
static std::jmp_buf s_jmp_env_expect_error;
static std::string s_jmp_msg;

ScopedErrorSettings tmp_settings;
static void error_callback(const char* /*msg*/, size_t /*msg_size*/)
{
++num_errors;
}
};

#define C4_EXPECT_ERROR_OCCURS(...) \
auto _testerroroccurs##__LINE__ = TestErrorOccurs(__VA_ARGS__)
auto _testerroroccurs##__LINE__ = c4::TestErrorOccurs(__VA_ARGS__)

#if C4_USE_ASSERT
# define C4_EXPECT_ASSERT_TRIGGERS(...) C4_EXPECT_ERROR_OCCURS(__VA_ARGS__)
Expand Down
33 changes: 6 additions & 27 deletions test/test_error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,26 @@
#endif
C4_SUPPRESS_WARNING_MSVC_WITH_PUSH(4611) // interaction between '_setjmp' and C++ object destruction is non-portable

C4_BEGIN_HIDDEN_NAMESPACE
bool got_an_error = false;
void error_callback(const char *msg, size_t msg_sz)
{
CHECK_EQ(strncmp(msg, "bla bla", msg_sz), 0);
CHECK_EQ(msg_sz, 7);
got_an_error = true;
}
inline c4::ScopedErrorSettings tmp_err()
{
got_an_error = false;
return c4::ScopedErrorSettings(c4::ON_ERROR_CALLBACK, error_callback);
}
C4_END_HIDDEN_NAMESPACE

namespace c4 {

TEST_CASE("Error.scoped_callback")
{
auto orig = get_error_callback();
{
auto tmp = tmp_err();
CHECK_EQ(get_error_callback() == error_callback, true);
C4_EXPECT_ERROR_OCCURS([&]{
CHECK_EQ(get_error_callback() != orig, true);
C4_ERROR("bla bla");
CHECK_EQ(got_an_error, true);
}
CHECK_EQ(get_error_callback() == orig, true);
});
}

} // namespace c4

TEST_CASE("Error.outside_of_c4_namespace")
{
auto orig = c4::get_error_callback();
{
auto tmp = tmp_err();
CHECK_EQ(c4::get_error_callback() == error_callback, true);
C4_EXPECT_ERROR_OCCURS([&]{
CHECK_EQ(c4::get_error_callback() != orig, true);
C4_ERROR("bla bla");
CHECK_EQ(got_an_error, true);
}
CHECK_EQ(c4::get_error_callback() == orig, true);
});
}


Expand Down
32 changes: 17 additions & 15 deletions test/test_memory_resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ TEST_CASE("aalloc_impl.error_bad_align")
{
#if defined(C4_POSIX)
#if !defined(C4_ASAN) && !defined(C4_LSAN) && !defined(C4_TSAN) && !defined(C4_UBSAN)
C4_EXPECT_ERROR_OCCURS(1);
auto *mem = detail::aalloc_impl(64, 9); // allocating with a non-power of two value is invalid
CHECK_EQ(mem, nullptr);
C4_EXPECT_ERROR_OCCURS([&]{
auto *mem = detail::aalloc_impl(64, 9); // allocating with a non-power of two value is invalid
(void)mem;
});
#endif
#endif
}
Expand All @@ -62,10 +63,11 @@ TEST_CASE("aalloc_impl.error_out_of_mem")
#if defined(C4_POSIX)
#if !defined(C4_ASAN) && !defined(C4_LSAN) && !defined(C4_TSAN) && !defined(C4_UBSAN)
if(sizeof(size_t) != 8) return; // valgrind complains that size is -1
C4_EXPECT_ERROR_OCCURS(1);
size_t sz = std::numeric_limits<size_t>::max() / 2u;
void const* mem = detail::aalloc_impl(sz);
CHECK_EQ(mem, nullptr);
C4_EXPECT_ERROR_OCCURS([&]{
size_t sz = std::numeric_limits<size_t>::max() / 2u;
void const* mem = detail::aalloc_impl(sz);
(void)mem;
});
#endif
#endif
}
Expand Down Expand Up @@ -158,30 +160,30 @@ TEST_CASE("MemoryResourceLinearArr.reallocate")
TEST_CASE("MemoryResourceLinear.error_out_of_mem")
{
{
C4_EXPECT_ERROR_OCCURS(0);
MemoryResourceLinear mr(8);
mr.allocate(2);
}

{
C4_EXPECT_ERROR_OCCURS(2);
MemoryResourceLinear mr(8);
mr.allocate(9);
C4_EXPECT_ERROR_OCCURS([]{
MemoryResourceLinear mr(8);
mr.allocate(9);
});
}
}

TEST_CASE("MemoryResourceLinearArr.error_out_of_mem")
{
{
C4_EXPECT_ERROR_OCCURS(0);
MemoryResourceLinearArr<8> mr;
mr.allocate(2);
}

{
C4_EXPECT_ERROR_OCCURS(2);
MemoryResourceLinearArr<8> mr;
mr.allocate(9);
C4_EXPECT_ERROR_OCCURS([]{
MemoryResourceLinearArr<8> mr;
mr.allocate(9);
});
}
}

Expand Down
10 changes: 6 additions & 4 deletions test/test_szconv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,15 @@ test_szconv()
#if C4_USE_XASSERT
if((uint64_t)omax < (uint64_t)imax)
{
C4_EXPECT_ERROR_OCCURS();
O out = szconv<O>(imax);
C4_EXPECT_ERROR_OCCURS([&]{
O out = szconv<O>(imax);
});
}
else if((uint64_t)omax > (uint64_t)imax)
{
C4_EXPECT_ERROR_OCCURS();
I out = szconv<I>(omax);
C4_EXPECT_ERROR_OCCURS([&]{
I out = szconv<I>(omax);
});
}
#endif
}
Expand Down

0 comments on commit 3af19e7

Please sign in to comment.