Commit 9f86fccd authored by Dominik Charousset's avatar Dominik Charousset

Merge pull request #1515

parents 8f94dc06 0659e979
......@@ -5,3 +5,4 @@ set(CAF_LOG_LEVEL TRACE CACHE STRING "")
if(NOT MSVC AND NOT CMAKE_SYSTEM MATCHES BSD)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "")
endif()
set(CMAKE_CXX_FLAGS "-Werror")
......@@ -6,6 +6,7 @@ cmake.exe ^
-DCAF_ENABLE_ROBOT_TESTS=ON ^
-DBUILD_SHARED_LIBS=OFF ^
-DCMAKE_C_COMPILER=cl.exe ^
-DCMAKE_CXX_COMPILER=cl.exe
-DCMAKE_CXX_COMPILER=cl.exe ^
-DCMAKE_CXX_FLAGS="/WX"
cmake.exe --build build --parallel %NUMBER_OF_PROCESSORS% --target install --config debug || exit \b 1
......@@ -13,7 +13,7 @@ config = [
'build',
'tests',
],
// Default CMake flags the builds.
// Default CMake flags for the builds.
buildFlags: [
'CAF_ENABLE_ACTOR_PROFILER:BOOL=ON',
'CAF_ENABLE_EXAMPLES:BOOL=ON',
......@@ -26,51 +26,81 @@ config = [
numCores: 4,
tags: ['docker'],
builds: ['release'],
extraBuildFlags: [
'CMAKE_CXX_FLAGS:STRING=-Werror',
],
]],
['almalinux-9', [ // EOL: May 2032
numCores: 4,
tags: ['docker'],
builds: ['release'],
extraBuildFlags: [
'CMAKE_CXX_FLAGS:STRING=-Werror',
],
]],
['alpinelinux-3.18', [ // EOL: May 2025
numCores: 4,
tags: ['docker'],
builds: ['release'],
extraBuildFlags: [
'CMAKE_CXX_FLAGS:STRING=-Werror -Wno-maybe-uninitialized -Wno-array-bounds',
],
]],
['centos-7', [ // EOL July 2024
numCores: 4,
tags: ['docker'],
builds: ['release'],
extraBuildFlags: [
'CMAKE_CXX_FLAGS:STRING=-Werror',
],
]],
['debian-10', [ // EOL June 2024
numCores: 4,
tags: ['docker'],
builds: ['release'],
extraBuildFlags: [
'CMAKE_CXX_FLAGS:STRING=-Werror',
],
]],
['debian-11', [ // EOL June 2026
numCores: 4,
tags: ['docker'],
builds: ['release'],
extraBuildFlags: [
'CMAKE_CXX_FLAGS:STRING=-Werror',
],
]],
['fedora-37', [ // EOL December 2023
numCores: 4,
tags: ['docker'],
builds: ['release'],
extraBuildFlags: [
'CMAKE_CXX_FLAGS:STRING=-Werror -Wno-maybe-uninitialized -Wno-array-bounds',
],
]],
['fedora-38', [ // EOL June 2024
numCores: 4,
tags: ['docker'],
builds: ['release'],
extraBuildFlags: [
'CMAKE_CXX_FLAGS:STRING=-Werror -Wno-maybe-uninitialized -Wno-array-bounds',
],
]],
['ubuntu-20.04', [ // April 2025
numCores: 4,
tags: ['docker'],
builds: ['release'],
extraBuildFlags: [
'CMAKE_CXX_FLAGS:STRING=-Werror',
],
]],
['ubuntu-22.04', [ // April 2027
numCores: 4,
tags: ['docker'],
builds: ['release'],
extraBuildFlags: [
'CMAKE_CXX_FLAGS:STRING=-Werror',
],
]],
// Debug build with exceptions disabled.
['fedora-38:no-exceptions', [
......@@ -81,7 +111,7 @@ config = [
'CAF_LOG_LEVEL:STRING=TRACE',
'CAF_ENABLE_ROBOT_TESTS:BOOL=ON',
'CAF_ENABLE_EXCEPTIONS:BOOL=OFF',
'CMAKE_CXX_FLAGS:STRING=-fno-exceptions',
'CMAKE_CXX_FLAGS:STRING=-Werror -fno-exceptions',
],
]],
// Debug build for LeakSanitizer.
......@@ -109,6 +139,7 @@ config = [
'CAF_LOG_LEVEL:STRING=TRACE',
'CAF_ENABLE_ROBOT_TESTS:BOOL=ON',
'CAF_SANITIZERS:STRING=address,undefined',
'CMAKE_CXX_FLAGS:STRING=-Werror',
],
extraBuildEnv: [
'CXXFLAGS=-fno-sanitize-recover=undefined -D_GLIBCXX_DEBUG',
......
......@@ -172,7 +172,7 @@ struct variant_inspector_traits<shape_ptr> {
// Assigns a value to x.
template <class U>
static void assign(value_type& x, U value) {
static void assign(value_type& x, [[maybe_unused]] U value) {
if constexpr (std::is_same_v<U, none_t>)
x.reset();
else
......
......@@ -32,7 +32,8 @@ public:
}
template <class ErrorPolicy, class TimePoint>
read_result pull(ErrorPolicy policy, T& item, TimePoint timeout) {
read_result
pull(ErrorPolicy policy, T& item, [[maybe_unused]] TimePoint timeout) {
if (!buf_) {
return abort_reason_ ? read_result::abort : read_result::stop;
}
......
......@@ -41,7 +41,6 @@ time_t tm_to_time_t(tm& time_buf) noexcept {
} // namespace
#else
# define _GNU_SOURCE
# include <ctime>
# include <ratio>
......
......@@ -89,6 +89,9 @@
# define CAF_PUSH_DEPRECATED_WARNING \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
# define CAF_PUSH_UNUSED_RESULT_WARNING \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wunused-result\"")
# define CAF_POP_WARNINGS \
_Pragma("clang diagnostic pop")
# define CAF_ANNOTATE_FALLTHROUGH [[clang::fallthrough]]
......@@ -118,6 +121,9 @@
# define CAF_PUSH_DEPRECATED_WARNING \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
# define CAF_PUSH_UNUSED_RESULT_WARNING \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wunused-result\"")
# define CAF_POP_WARNINGS \
_Pragma("GCC diagnostic pop")
# if __GNUC__ >= 7
......
......@@ -167,12 +167,12 @@ type_id_t config_value::type_id() const noexcept {
error_code<sec> config_value::default_construct(type_id_t id) {
switch (id) {
case type_id_v<bool>:
set(false);
data_ = false;
return sec::none;
case type_id_v<double>:
case type_id_v<float>:
case type_id_v<long double>:
set(0.0);
data_ = 0.0;
return sec::none;
case type_id_v<int16_t>:
case type_id_v<int32_t>:
......@@ -182,16 +182,16 @@ error_code<sec> config_value::default_construct(type_id_t id) {
case type_id_v<uint32_t>:
case type_id_v<uint64_t>:
case type_id_v<uint8_t>:
set(0);
data_ = int64_t{0};
return sec::none;
case type_id_v<std::string>:
set(std::string{});
data_ = std::string{};
return sec::none;
case type_id_v<timespan>:
set(timespan{});
data_ = timespan{};
return sec::none;
case type_id_v<uri>:
set(uri{});
data_ = uri{};
return sec::none;
default:
if (auto meta = detail::global_meta_object_or_null(id)) {
......
......@@ -99,8 +99,8 @@ public:
template <class T, class E = detail::enable_if_t<
!std::is_same_v<detail::decay_t<T>, config_value>>>
explicit config_value(T&& x) {
set(std::forward<T>(x));
explicit config_value(T&& x) : data_(lift(std::forward<T>(x))) {
// nop
}
config_value& operator=(config_value&& other) = default;
......@@ -110,7 +110,7 @@ public:
template <class T, class E = detail::enable_if_t<
!std::is_same_v<detail::decay_t<T>, config_value>>>
config_value& operator=(T&& x) {
set(std::forward<T>(x));
data_ = lift(std::forward<T>(x));
return *this;
}
......@@ -271,49 +271,35 @@ private:
// -- auto conversion of related types ---------------------------------------
template <class T>
void set_range(T& xs, std::true_type) {
auto& dict = as_dictionary();
dict.clear();
for (auto& [key, val] : xs)
dict.emplace(key, std::move(val));
}
template <class T>
void set_range(T& xs, std::false_type) {
auto& ls = as_list();
ls.clear();
ls.insert(ls.end(), std::make_move_iterator(xs.begin()),
std::make_move_iterator(xs.end()));
}
template <class T>
void set(T x) {
auto lift(T x) {
if constexpr (detail::is_config_value_type_v<T>) {
data_ = std::move(x);
return x;
} else if constexpr (std::is_integral_v<T>) {
data_ = static_cast<int64_t>(x);
} else if constexpr (std::is_convertible<T, const char*>::value) {
data_ = std::string{x};
return static_cast<int64_t>(x);
} else if constexpr (std::is_same_v<T, float>) {
return static_cast<double>(x);
} else if constexpr (std::is_convertible_v<T, const char*>) {
return std::string{x};
} else if constexpr (std::is_same_v<T, std::string_view>) {
return std::string{x};
} else {
static_assert(detail::is_iterable<T>::value);
static_assert(detail::is_iterable_v<T>);
using value_type = typename T::value_type;
detail::bool_token<detail::is_pair_v<value_type>> is_map_type;
set_range(x, is_map_type);
if constexpr (detail::is_pair<value_type>::value) {
dictionary result;
for (auto& [key, val] : x)
result.emplace(std::move(key), std::move(val));
return result;
} else {
list result;
result.reserve(x.size());
for (auto& val : x)
result.emplace_back(std::move(val));
return result;
}
}
}
void set(float x) {
data_ = static_cast<double>(x);
}
void set(const char* x) {
data_ = std::string{x};
}
void set(std::string_view x) {
data_ = std::string{x.begin(), x.end()};
}
// -- member variables -------------------------------------------------------
variant_type data_;
......
......@@ -140,7 +140,7 @@ public:
template <class T>
void value(T&& x) {
result = config_value{std::forward<T>(x)};
result = std::forward<T>(x);
}
config_list_consumer begin_list();
......
......@@ -22,7 +22,8 @@ public:
// nop
}
void actor_exited(const error& fail_state, execution_unit* host) override {
void actor_exited(const error& fail_state,
[[maybe_unused]] execution_unit* host) override {
if constexpr (num_args == 0)
fn_();
else if constexpr (num_args == 1)
......
......@@ -56,7 +56,7 @@ bool load(deserializer& source, void* ptr) {
}
template <class T>
void stringify(std::string& buf, const void* ptr) {
void stringify(std::string& buf, [[maybe_unused]] const void* ptr) {
if constexpr (is_allowed_unsafe_message_type_v<T>) {
auto tn = type_name_v<T>;
buf.insert(buf.end(), tn.begin(), tn.end());
......
......@@ -95,7 +95,8 @@ void read_negative_number(State& ps, Consumer& consumer, EnableFloat = {},
transition(neg_dec, decimal_chars, sub_ascii<10>(result, ch),
pec::integer_underflow)
fsm_epsilon_static_if(enable_float,
read_floating_point(ps, consumer, odbl{result}, true),
read_floating_point(ps, consumer,
odbl{static_cast<double>(result)}, true),
done, "eE", g.disable())
transition_static_if(enable_float || enable_range, neg_dot, '.')
}
......@@ -104,7 +105,8 @@ void read_negative_number(State& ps, Consumer& consumer, EnableFloat = {},
read_number_range(ps, consumer, result),
done, '.', g.disable())
fsm_epsilon_static_if(enable_float,
read_floating_point(ps, consumer, odbl{result}, true),
read_floating_point(ps, consumer,
odbl{static_cast<double>(result)}, true),
done, any_char, g.disable())
epsilon(done)
}
......@@ -174,7 +176,8 @@ void read_positive_number(State& ps, Consumer& consumer, EnableFloat = {},
transition(pos_dec, decimal_chars, add_ascii<10>(result, ch),
pec::integer_overflow)
fsm_epsilon_static_if(enable_float,
read_floating_point(ps, consumer, odbl{result}),
read_floating_point(ps, consumer,
odbl{static_cast<double>(result)}),
done, "eE", g.disable())
transition_static_if(enable_float || enable_range, pos_dot, '.')
}
......@@ -184,7 +187,8 @@ void read_positive_number(State& ps, Consumer& consumer, EnableFloat = {},
read_number_range(ps, consumer, result),
done, '.', g.disable())
fsm_epsilon_static_if(enable_float,
read_floating_point(ps, consumer, odbl{result}),
read_floating_point(ps, consumer,
odbl{static_cast<double>(result)}),
done, any_char, g.disable())
epsilon(done)
}
......
......@@ -4,6 +4,7 @@
#pragma once
#include "caf/config.hpp"
#include "caf/detail/is_complete.hpp"
#include "caf/detail/is_one_of.hpp"
#include "caf/detail/type_list.hpp"
......@@ -840,24 +841,6 @@ public:
static constexpr bool value = sfinae_type::value;
};
template <class T, class Arg>
struct can_apply {
template <class U>
static auto sfinae(U* x)
-> decltype(CAF_IGNORE_UNUSED(x->apply(std::declval<Arg>())),
std::true_type{});
template <class U>
static auto sfinae(...) -> std::false_type;
using type = decltype(sfinae<T>(nullptr));
static constexpr bool value = type::value;
};
template <class T, class Arg>
constexpr bool can_apply_v = can_apply<T, Arg>::value;
/// Evaluates to `true` for all types that specialize `std::tuple_size`, i.e.,
/// `std::tuple`, `std::pair`, and `std::array`.
template <class T>
......@@ -1077,8 +1060,17 @@ constexpr bool is_64bit_integer_v = std::is_same_v<T, int64_t>
/// Checks whether `T` has a static member function called `init_host_system`.
template <class T>
struct has_init_host_system {
// GNU g++ 8.5.0 (almalinux-8) has a known bug where [[nodiscard] values are
// reported as warnings, even in unevaluated context.
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89070
#if !defined(__clang__) && defined(__GNUC__)
CAF_PUSH_UNUSED_RESULT_WARNING
#endif
template <class U>
static auto sfinae(U*) -> decltype(U::init_host_system(), std::true_type());
#if !defined(__clang__) && defined(__GNUC__)
CAF_POP_WARNINGS
#endif
template <class U>
static auto sfinae(...) -> std::false_type;
......
......@@ -802,7 +802,7 @@ public:
if (has_value())
return f();
else
return res_t{std::move(*error_)};
return res_t{*error_};
}
template <class F>
......@@ -862,7 +862,7 @@ public:
if constexpr (std::is_void_v<res_t>) {
if (!has_value())
f(std::move(*error_));
return std::move(*this);
return *this;
} else {
static_assert(std::is_same_v<expected, res_t>,
"F must return expected<T> or void");
......@@ -914,7 +914,7 @@ public:
if (has_value())
return detail::expected_from_fn(std::forward<F>(f));
else
return expected<res_t>{std::move(*error_)};
return expected<res_t>{*error_};
}
template <class F>
......
......@@ -28,7 +28,7 @@ public:
take_last& operator=(const take_last&) = default;
template <class Next, class... Steps>
bool on_next(const input_type& item, Next& next, Steps&... steps) {
bool on_next(const input_type& item, Next&, Steps&...) {
elements_.push_back(item);
return true;
}
......
......@@ -526,7 +526,7 @@ scheduled_actor::categorize(mailbox_element& x) {
auto& what = content.get_as<std::string>(2);
if (what == "info") {
CAF_LOG_DEBUG("reply to 'info' message");
rp.deliver(ok_atom_v, std::move(what), strong_actor_ptr{ctrl()}, name());
rp.deliver(ok_atom_v, what, strong_actor_ptr{ctrl()}, name());
} else {
rp.deliver(make_error(sec::unsupported_sys_key));
}
......@@ -834,8 +834,8 @@ auto scheduled_actor::reactivate(mailbox_element& x) -> activation_result {
handle_exception(std::current_exception());
}
finalize();
return activation_result::terminated;
#endif // CAF_ENABLE_EXCEPTIONS
return activation_result::terminated;
}
// -- behavior management ----------------------------------------------------
......
......@@ -298,6 +298,8 @@ bool operator!=(std::nullptr_t, const typed_actor<Xs...>& x) noexcept {
return !(x == nullptr);
}
CAF_PUSH_DEPRECATED_WARNING
/// Returns a new actor that implements the composition `f.g(x) = f(g(x))`.
/// @relates typed_actor
template <class... Xs, class... Ys>
......@@ -314,6 +316,8 @@ operator*(typed_actor<Xs...> f, typed_actor<Ys...> g) {
actor_cast<strong_actor_ptr>(std::move(g)), std::move(mts));
}
CAF_POP_WARNINGS
} // namespace caf
// allow typed_actor to be used in hash maps
......
......@@ -12,7 +12,7 @@ using namespace caf;
#define ASSERT_COMPILES(expr, msg) \
static_assert( \
std::is_void_v<decltype(std::declval<scheduled_actor*>()->expr)>, msg);
std::is_void_v<decltype(std::declval<scheduled_actor*>()->expr)>, msg)
namespace {
......
......@@ -29,7 +29,7 @@ struct builtin_arg_parser {
if (auto err = detail::parse(str, tmp); !err)
return tmp;
else
return {};
return std::nullopt;
}
};
......
......@@ -121,7 +121,7 @@ public:
if (auto res = caf::get_as<T>(val))
return std::move(*res);
}
return {};
return std::nullopt;
}
/// Executes the provided callable `f` for each field in the request header.
......
......@@ -434,7 +434,8 @@ public:
}
/// Handles an I/O event on given manager.
void handle(const socket_manager_ptr& mgr, short events, short revents) {
void handle(const socket_manager_ptr& mgr, [[maybe_unused]] short events,
short revents) {
CAF_LOG_TRACE(CAF_ARG2("socket", mgr->handle().id)
<< CAF_ARG(events) << CAF_ARG(revents));
CAF_ASSERT(mgr != nullptr);
......
......@@ -420,7 +420,7 @@ struct rejecting_fixture {
} // namespace
BEGIN_FIXTURE_SCOPE(rejecting_fixture);
BEGIN_FIXTURE_SCOPE(rejecting_fixture)
SCENARIO("apps can return errors to shut down the framing layer") {
GIVEN("an app that returns -1 for any frame it receives") {
......@@ -612,7 +612,7 @@ SCENARIO("the application shuts down on invalid frame fragments") {
}
}
END_FIXTURE_SCOPE();
END_FIXTURE_SCOPE()
TEST_CASE("empty closing payload is valid") {
auto error
......
......@@ -229,14 +229,14 @@ public:
/// Adds a predicate for the sender of the next message that matches only if
/// the sender is `src`.
evaluator&& from(const strong_actor_ptr& src) && {
from_ = value_predicate<strong_actor_ptr>{std::move(src)};
from_ = value_predicate<strong_actor_ptr>{src};
return std::move(*this);
}
/// Adds a predicate for the sender of the next message that matches only if
/// the sender is `src`.
evaluator&& from(const actor& src) && {
from_ = value_predicate<strong_actor_ptr>{std::move(src)};
from_ = value_predicate<strong_actor_ptr>{src};
return std::move(*this);
}
......@@ -244,7 +244,7 @@ public:
/// the sender is `src`.
template <class... Us>
evaluator&& from(const typed_actor<Us...>& src) && {
from_ = value_predicate<strong_actor_ptr>{std::move(src)};
from_ = value_predicate<strong_actor_ptr>{src};
return std::move(*this);
}
......
......@@ -190,7 +190,7 @@ int runner::run(int argc, char** argv) {
default_reporter->end_suite(suite_name);
}
default_reporter->stop();
return default_reporter->success() > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
return default_reporter->success() ? EXIT_SUCCESS : EXIT_FAILURE;
}
runner::parse_cli_result runner::parse_cli(int argc, char** argv) {
......
......@@ -9,7 +9,6 @@ using caf::test::block_type;
TEST("tests can contain different types of checks") {
auto& rep = caf::test::reporter::instance();
auto stats = rep.test_stats();
SECTION("check_ne checks for inequality") {
check_ne(0, 1);
should_fail([this]() { check_ne(0, 0); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment