From f5534295b3135aba6e5eafac0cec9a90b701e15f Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Tue, 14 Feb 2023 19:56:56 +0100 Subject: [PATCH 01/13] iox-#1394 Fix Axivion warnigs in functional_interface --- .../design/include/iox/detail/functional_interface.inl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/iceoryx_hoofs/design/include/iox/detail/functional_interface.inl b/iceoryx_hoofs/design/include/iox/detail/functional_interface.inl index 84fbf91b71..3db12c7108 100644 --- a/iceoryx_hoofs/design/include/iox/detail/functional_interface.inl +++ b/iceoryx_hoofs/design/include/iox/detail/functional_interface.inl @@ -66,8 +66,7 @@ template inline const ValueType& ExpectWithValue::expect(const StringType& msg) const& noexcept { using Self = ExpectWithValue; - // AXIVION Next Construct AutosarC++19_03-A5.2.3 : const_cast avoids code duplication, is safe since the constness - // of the return value is restored + // AXIVION Next Construct AutosarC++19_03-A5.2.3 : const_cast avoids code duplication, is safe since the constness of the return value is restored // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) return const_cast(const_cast(this)->expect(msg)); } @@ -84,8 +83,7 @@ template inline const ValueType&& ExpectWithValue::expect(const StringType& msg) const&& noexcept { using Self = ExpectWithValue; - // AXIVION Next Construct AutosarC++19_03-A5.2.3 : const_cast avoids code duplication, is safe since the constness - // of the return value is restored + // AXIVION Next Construct AutosarC++19_03-A5.2.3 : const_cast avoids code duplication, is safe since the constness of the return value is restored // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) return const_cast(std::move(const_cast(this)->expect(msg))); } From bc0b4d69a48f2982cc507e37d0786f0538b38075 Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Tue, 14 Feb 2023 19:57:48 +0100 Subject: [PATCH 02/13] iox-#1394 Fix Axivion warnigs in memory.hpp --- iceoryx_hoofs/memory/include/iox/memory.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/iceoryx_hoofs/memory/include/iox/memory.hpp b/iceoryx_hoofs/memory/include/iox/memory.hpp index 18556b64a5..915293a862 100644 --- a/iceoryx_hoofs/memory/include/iox/memory.hpp +++ b/iceoryx_hoofs/memory/include/iox/memory.hpp @@ -27,10 +27,10 @@ namespace iox /// @note value + alignment - 1 must not exceed the maximum value for type T /// @note alignment must be a power of two template -// AXIVION Next Construct AutosarC++19_03-A2.10.5, AutosarC++19_03-M17.0.3: The function is in the 'iox' namespace which prevents easy misuse +// AXIVION Next Construct AutosarC++19_03-A2.10.5, AutosarC++19_03-M17.0.3 : The function is in the 'iox' namespace which prevents easy misuse T align(const T value, const T alignment) noexcept { - return (value + (alignment - 1)) & (-alignment); + return (value + (alignment - 1)) & (~alignment + 1); } /// @brief allocates aligned memory which can only be free'd by alignedFree @@ -45,6 +45,7 @@ void alignedFree(void* const memory) noexcept; /// template recursion stopper for maximum alignment calculation template +// AXIVION Next Construct AutosarC++19_03-A2.10.5 : The function is in the 'iox' namespace which prevents easy misuse constexpr std::size_t maxAlignment() noexcept { return S; @@ -52,9 +53,11 @@ constexpr std::size_t maxAlignment() noexcept /// calculate maximum alignment of supplied types template +// AXIVION Next Construct AutosarC++19_03-A2.10.5 : The function is in the 'iox' namespace which prevents easy misuse constexpr std::size_t maxAlignment() noexcept { - return (alignof(T) > maxAlignment()) ? alignof(T) : maxAlignment(); + auto remainingMaxAlignment = maxAlignment(); + return (alignof(T) > remainingMaxAlignment) ? alignof(T) : remainingMaxAlignment; } /// template recursion stopper for maximum size calculation From d8a091fafe8a78caede4b867c73b6be334220f0e Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Tue, 14 Feb 2023 20:01:17 +0100 Subject: [PATCH 03/13] iox-#1394 Fix Axivion warnigs in bump_allocator --- .../memory/include/iox/bump_allocator.hpp | 2 +- .../memory/source/bump_allocator.cpp | 24 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/iceoryx_hoofs/memory/include/iox/bump_allocator.hpp b/iceoryx_hoofs/memory/include/iox/bump_allocator.hpp index 569875a20c..17aa0f5fe7 100644 --- a/iceoryx_hoofs/memory/include/iox/bump_allocator.hpp +++ b/iceoryx_hoofs/memory/include/iox/bump_allocator.hpp @@ -57,7 +57,7 @@ class BumpAllocator void deallocate() noexcept; private: - cxx::byte_t* m_startAddress{nullptr}; + uint64_t m_startAddress{0U}; uint64_t m_length{0U}; uint64_t m_currentPosition{0U}; }; diff --git a/iceoryx_hoofs/memory/source/bump_allocator.cpp b/iceoryx_hoofs/memory/source/bump_allocator.cpp index 961910a76e..385427de05 100644 --- a/iceoryx_hoofs/memory/source/bump_allocator.cpp +++ b/iceoryx_hoofs/memory/source/bump_allocator.cpp @@ -25,7 +25,9 @@ namespace iox { BumpAllocator::BumpAllocator(void* const startAddress, const uint64_t length) noexcept - : m_startAddress(static_cast(startAddress)) + // AXIVION Next Construct AutosarC++19_03-A5.2.4 : required for low level memory management + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + : m_startAddress(reinterpret_cast(startAddress)) , m_length(length) { } @@ -40,20 +42,20 @@ cxx::expected BumpAllocator::allocate(const uint64_t return cxx::error(BumpAllocatorError::REQUESTED_ZERO_SIZED_MEMORY); } - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) required for low level pointer alignment - uint64_t currentAddress = reinterpret_cast(m_startAddress) + m_currentPosition; - uint64_t alignedPosition = align(currentAddress, static_cast(alignment)); + const uint64_t currentAddress{m_startAddress + m_currentPosition}; + uint64_t alignedPosition{align(currentAddress, alignment)}; - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) required for low level pointer alignment - alignedPosition -= reinterpret_cast(m_startAddress); + alignedPosition -= m_startAddress; - cxx::byte_t* allocation = nullptr; + void* allocation{nullptr}; - if (m_length >= alignedPosition + size) + auto nextPosition = alignedPosition + size; + if (m_length >= nextPosition) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) low-level memory management - allocation = m_startAddress + alignedPosition; - m_currentPosition = alignedPosition + size; + // AXIVION Next Construct AutosarC++19_03-A5.2.4 : required for low level memory management + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast, performance-no-int-to-ptr) + allocation = reinterpret_cast(m_startAddress + alignedPosition); + m_currentPosition = nextPosition; } else { From a30971d5162b004be953ff61e1a7238bd974b225 Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Tue, 14 Feb 2023 20:05:18 +0100 Subject: [PATCH 04/13] iox-#1394 Fix Axivion warnigs in relative_pointer --- .../include/iceoryx_hoofs/memory/relative_pointer.inl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/memory/relative_pointer.inl b/iceoryx_hoofs/include/iceoryx_hoofs/memory/relative_pointer.inl index c0246b168f..c11123fa06 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/memory/relative_pointer.inl +++ b/iceoryx_hoofs/include/iceoryx_hoofs/memory/relative_pointer.inl @@ -203,8 +203,7 @@ inline T* RelativePointer::getPtr(const segment_id_t id, const offset_t offse return nullptr; } const auto* const basePtr = getBasePtr(id); - // AXIVION Next Construct AutosarC++19_03-A5.2.4, AutosarC++19_03-M5.2.8, AutosarC++19_03-M5.2.6, AutosarC++19_03-M5.2.9 : Cast - // needed for pointer arithmetic + // AXIVION Next Construct AutosarC++19_03-A5.2.4, AutosarC++19_03-M5.2.8, AutosarC++19_03-M5.2.6, AutosarC++19_03-M5.2.9 : Cast needed for pointer arithmetic // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast, performance-no-int-to-ptr) return reinterpret_cast(offset + reinterpret_cast(basePtr)); } From 94c95e117732823ca1f6fa7559d26f0f7c177a71 Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Tue, 14 Feb 2023 20:05:44 +0100 Subject: [PATCH 05/13] iox-#1394 Fix Axivion warnigs in size.hpp --- iceoryx_hoofs/primitives/include/iox/size.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iceoryx_hoofs/primitives/include/iox/size.hpp b/iceoryx_hoofs/primitives/include/iox/size.hpp index 5fbf3faa00..d0af287873 100644 --- a/iceoryx_hoofs/primitives/include/iox/size.hpp +++ b/iceoryx_hoofs/primitives/include/iox/size.hpp @@ -31,8 +31,8 @@ namespace iox /// @param[in] The actual content of the array is not of interest. Its just the capacity of the array that matters. /// @return Returns the capacity of the array at compile time. template -// AXIVION Next Construct AutosarC++19_03-A18.1.1:returning capacity of C array at compile time is safe, no -// possibility of out of bounds access +// AXIVION Next Construct AutosarC++19_03-A2.10.5, AutosarC++19_03-M17.0.3 : The function is in the 'iox' namespace which prevents easy misuse +// AXIVION Next Construct AutosarC++19_03-A18.1.1 : returning capacity of C array at compile time is safe, no possibility of out of bounds access // NOLINTNEXTLINE(hicpp-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) static constexpr uint64_t size(T const (&/*notInterested*/)[CapacityValue]) noexcept { From d41f6e089be08d926450b396ef443105c2516592 Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Tue, 14 Feb 2023 20:05:59 +0100 Subject: [PATCH 06/13] iox-#1394 Fix Axivion warnigs in duration --- .../moduletests/test_time_unit_duration.cpp | 54 ++++++++--- .../time/include/iox/detail/duration.inl | 90 ++++++++++--------- iceoryx_hoofs/time/include/iox/duration.hpp | 21 ++--- iceoryx_hoofs/time/source/duration.cpp | 20 +++-- 4 files changed, 111 insertions(+), 74 deletions(-) diff --git a/iceoryx_hoofs/test/moduletests/test_time_unit_duration.cpp b/iceoryx_hoofs/test/moduletests/test_time_unit_duration.cpp index 1800923e96..bd1473e226 100644 --- a/iceoryx_hoofs/test/moduletests/test_time_unit_duration.cpp +++ b/iceoryx_hoofs/test/moduletests/test_time_unit_duration.cpp @@ -22,6 +22,7 @@ #include "test.hpp" #include #include +#include #include namespace @@ -2138,40 +2139,69 @@ TEST(Duration_test, MultiplyDurationResultsInSaturationDueToNanoseconds) EXPECT_THAT(DURATION * MULTIPLICATOR, Eq(DurationAccessor::max())); } -TEST(Duration_test, MultiplyZeroDurationWithNaNDoubleResultsInZeroDuration) +TEST(Duration_test, MultiplyZeroDurationWithQuietNaNResultsInZeroDuration) { ::testing::Test::RecordProperty("TEST_ID", "4639ac39-639f-4df9-b591-05714f1cbc30"); - EXPECT_THAT(0_s * NAN, Eq(0_s)); + EXPECT_THAT(0_s * std::numeric_limits::quiet_NaN(), Eq(0_s)); + EXPECT_THAT(0_s * std::numeric_limits::quiet_NaN(), Eq(0_s)); + EXPECT_THAT(0_s * std::numeric_limits::quiet_NaN(), Eq(0_s)); } -TEST(Duration_test, MultiplyMaxDurationWithNaNDoubleResultsInMaxDuration) +TEST(Duration_test, MultiplyMaxDurationWithQuietNaNResultsInMaxDuration) { ::testing::Test::RecordProperty("TEST_ID", "e09e4248-284d-4ab7-993b-1474ac5e3b11"); - EXPECT_THAT(DurationAccessor::max() * NAN, Eq(DurationAccessor::max())); + EXPECT_THAT(DurationAccessor::max() * std::numeric_limits::quiet_NaN(), Eq(DurationAccessor::max())); + EXPECT_THAT(DurationAccessor::max() * std::numeric_limits::quiet_NaN(), Eq(DurationAccessor::max())); + EXPECT_THAT(DurationAccessor::max() * std::numeric_limits::quiet_NaN(), Eq(DurationAccessor::max())); } -TEST(Duration_test, MultiplyZeroDurationWithPosInfDoubleResultsInZeroDuration) +TEST(Duration_test, MultiplyZeroDurationWithSignalingNaNResultsInZeroDuration) +{ + ::testing::Test::RecordProperty("TEST_ID", "5007488d-43e8-456b-97b5-f00832a6b5cf"); + EXPECT_THAT(0_s * std::numeric_limits::signaling_NaN(), Eq(0_s)); + EXPECT_THAT(0_s * std::numeric_limits::signaling_NaN(), Eq(0_s)); + EXPECT_THAT(0_s * std::numeric_limits::signaling_NaN(), Eq(0_s)); +} + +TEST(Duration_test, MultiplyMaxDurationWithSignalingNaNResultsInMaxDuration) +{ + ::testing::Test::RecordProperty("TEST_ID", "80e0e30c-6fc2-41d6-a46e-63f6d5ade869"); + EXPECT_THAT(DurationAccessor::max() * std::numeric_limits::signaling_NaN(), Eq(DurationAccessor::max())); + EXPECT_THAT(DurationAccessor::max() * std::numeric_limits::signaling_NaN(), Eq(DurationAccessor::max())); + EXPECT_THAT(DurationAccessor::max() * std::numeric_limits::signaling_NaN(), + Eq(DurationAccessor::max())); +} + +TEST(Duration_test, MultiplyZeroDurationWithPosInfResultsInZeroDuration) { ::testing::Test::RecordProperty("TEST_ID", "71dea32f-1200-4df2-8eff-ea607f1b6a01"); - EXPECT_THAT(0_s * INFINITY, Eq(0_ns)); + EXPECT_THAT(0_s * std::numeric_limits::infinity(), Eq(0_ns)); + EXPECT_THAT(0_s * std::numeric_limits::infinity(), Eq(0_ns)); + EXPECT_THAT(0_s * std::numeric_limits::infinity(), Eq(0_ns)); } -TEST(Duration_test, MultiplyMaxDurationWithPosInfDoubleResultsInMaxDuration) +TEST(Duration_test, MultiplyMaxDurationWithPosInfResultsInMaxDuration) { ::testing::Test::RecordProperty("TEST_ID", "5f66a93a-2df1-4f7d-abbf-03d5424a1534"); - EXPECT_THAT(DurationAccessor::max() * INFINITY, Eq(DurationAccessor::max())); + EXPECT_THAT(DurationAccessor::max() * std::numeric_limits::infinity(), Eq(DurationAccessor::max())); + EXPECT_THAT(DurationAccessor::max() * std::numeric_limits::infinity(), Eq(DurationAccessor::max())); + EXPECT_THAT(DurationAccessor::max() * std::numeric_limits::infinity(), Eq(DurationAccessor::max())); } -TEST(Duration_test, MultiplyZeroDurationWithNegInfDoubleResultsInZeroDuration) +TEST(Duration_test, MultiplyZeroDurationWithNegInfResultsInZeroDuration) { ::testing::Test::RecordProperty("TEST_ID", "3931a3df-e09f-414a-8a1e-64bcb1e010b7"); - EXPECT_THAT(0_s * (INFINITY * -1.0), Eq(0_ns)); + EXPECT_THAT(0_s * (std::numeric_limits::infinity() * -1.0), Eq(0_ns)); + EXPECT_THAT(0_s * (std::numeric_limits::infinity() * -1.0), Eq(0_ns)); + EXPECT_THAT(0_s * (std::numeric_limits::infinity() * -1.0), Eq(0_ns)); } -TEST(Duration_test, MultiplyMaxDurationWithNegInfDoubleResultsInZeroDuration) +TEST(Duration_test, MultiplyMaxDurationWithNegInfResultsInZeroDuration) { ::testing::Test::RecordProperty("TEST_ID", "9f563db0-85fa-4558-8928-8fe730f3ff47"); - EXPECT_THAT(DurationAccessor::max() * (INFINITY * -1.0), Eq(0_ns)); + EXPECT_THAT(DurationAccessor::max() * (std::numeric_limits::infinity() * -1.0), Eq(0_ns)); + EXPECT_THAT(DurationAccessor::max() * (std::numeric_limits::infinity() * -1.0), Eq(0_ns)); + EXPECT_THAT(DurationAccessor::max() * (std::numeric_limits::infinity() * -1.0), Eq(0_ns)); } TEST(Duration_test, MultiplyDurationWithMinimalFloatResultsInZero) diff --git a/iceoryx_hoofs/time/include/iox/detail/duration.inl b/iceoryx_hoofs/time/include/iox/detail/duration.inl index d9a6786dd8..2ea9125d35 100644 --- a/iceoryx_hoofs/time/include/iox/detail/duration.inl +++ b/iceoryx_hoofs/time/include/iox/detail/duration.inl @@ -79,9 +79,9 @@ inline constexpr uint64_t Duration::positiveValueOrClampToZero(const T value) no template inline constexpr Duration Duration::fromNanoseconds(const T value) noexcept { - auto clampedValue = positiveValueOrClampToZero(value); - auto seconds = static_cast(clampedValue / Duration::NANOSECS_PER_SEC); - auto nanoseconds = static_cast(clampedValue % Duration::NANOSECS_PER_SEC); + const auto clampedValue = positiveValueOrClampToZero(value); + const auto seconds = static_cast(clampedValue / Duration::NANOSECS_PER_SEC); + const auto nanoseconds = static_cast(clampedValue % Duration::NANOSECS_PER_SEC); return createDuration(seconds, nanoseconds); } template @@ -108,7 +108,7 @@ inline constexpr Duration Duration::fromSeconds(const T value) noexcept const auto clampedValue = positiveValueOrClampToZero(value); constexpr Duration::Seconds_t MAX_SECONDS_BEFORE_OVERFLOW{std::numeric_limits::max()}; - // AXIVION Next Construct AutosarC++19_03-M0.1.2, AutosarC++19_03-M0.1.9: False positive, platform-dependent + // AXIVION Next Construct AutosarC++19_03-M0.1.2, AutosarC++19_03-M0.1.9, FaultDetection-DeadBranches : False positive, platform-dependent if (clampedValue > MAX_SECONDS_BEFORE_OVERFLOW) { return Duration::max(); @@ -150,19 +150,19 @@ inline constexpr Duration Duration::fromDays(const T value) noexcept return Duration{static_cast(clampedValue * SECS_PER_DAY), 0U}; } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Argument is larger than two words inline constexpr Duration::Duration(const struct timeval& value) noexcept : Duration(static_cast(value.tv_sec), static_cast(value.tv_usec) * NANOSECS_PER_MICROSEC) { } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Argument is larger than two words inline constexpr Duration::Duration(const struct timespec& value) noexcept : Duration(static_cast(value.tv_sec), static_cast(value.tv_nsec)) { } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Argument is larger than two words inline constexpr Duration::Duration(const struct itimerspec& value) noexcept : Duration(value.it_interval) { @@ -268,7 +268,7 @@ inline constexpr struct timeval Duration::timeval() const noexcept return {static_cast(m_seconds), static_cast(m_nanoseconds / NANOSECS_PER_MICROSEC)}; } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Argument is larger than two words inline constexpr Duration Duration::operator+(const Duration& rhs) const noexcept { Seconds_t seconds{m_seconds + rhs.m_seconds}; @@ -287,14 +287,14 @@ inline constexpr Duration Duration::operator+(const Duration& rhs) const noexcep return sum; } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Argument is larger than two words inline constexpr Duration& Duration::operator+=(const Duration& rhs) noexcept { *this = *this + rhs; return *this; } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Argument is larger than two words inline constexpr Duration Duration::operator-(const Duration& rhs) const noexcept { if (*this < rhs) @@ -302,7 +302,7 @@ inline constexpr Duration Duration::operator-(const Duration& rhs) const noexcep return Duration::zero(); } Seconds_t seconds{m_seconds - rhs.m_seconds}; - // AXIVION Next Construct AutosarC++19_03-M0.1.9, AutosarC++19_03-A0.1.1 : False positive, variable IS used + // AXIVION Next Construct AutosarC++19_03-M0.1.9, AutosarC++19_03-A0.1.1, FaultDetection-UnusedAssignments : False positive, variable IS used Nanoseconds_t nanoseconds{0U}; if (m_nanoseconds >= rhs.m_nanoseconds) { @@ -310,13 +310,14 @@ inline constexpr Duration Duration::operator-(const Duration& rhs) const noexcep } else { + // AXIVION Next Construct AutosarC++19_03-A4.7.1, AutosarC++19_03-M0.3.1, FaultDetection-IntegerOverflow : It is ensured that m_nanoseconds is never larger than NANOSECS_PER_SEC nanoseconds = (NANOSECS_PER_SEC - rhs.m_nanoseconds) + m_nanoseconds; --seconds; } return createDuration(seconds, nanoseconds); } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Argument is larger than two words inline constexpr Duration& Duration::operator-=(const Duration& rhs) noexcept { *this = *this - rhs; @@ -327,7 +328,10 @@ template inline constexpr Duration Duration::multiplyWith(const std::enable_if_t::value, T>& rhs) const noexcept { - // operator*(...) takes care of negative values and 0 for rhs + if ((rhs <= static_cast(0)) || (*this == Duration::zero())) + { + return Duration::zero(); + } static_assert(sizeof(T) <= sizeof(Seconds_t), "only integer types with less or equal to size of uint64_t are allowed for multiplication"); @@ -340,7 +344,7 @@ Duration::multiplyWith(const std::enable_if_t::value, { return Duration::max(); } - auto durationFromSeconds = Duration(m_seconds * multiplicator, 0U); + const auto durationFromSeconds = Duration(m_seconds * multiplicator, 0U); // the m_nanoseconds multiplication cannot exceed the limits of a Duration, since m_nanoseconds is always less than // a second and m_seconds can hold 64 bits and the multiplicator is at max 64 bits @@ -357,8 +361,8 @@ Duration::multiplyWith(const std::enable_if_t::value, // multiplicator and another one with the upper 32 bits; // this is the easy part with the lower 32 bits - uint64_t multiplicatorLow{static_cast(multiplicator)}; - Duration durationFromNanosecondsLow{Duration::fromNanoseconds(m_nanoseconds * multiplicatorLow)}; + const uint64_t multiplicatorLow{static_cast(multiplicator)}; + const Duration durationFromNanosecondsLow{Duration::fromNanoseconds(m_nanoseconds * multiplicatorLow)}; // this is the complicated part with the upper 32 bits; // the m_nanoseconds are multiplied with the upper 32 bits of the multiplicator shifted by 32 bit to the right, thus @@ -381,12 +385,13 @@ Duration::multiplyWith(const std::enable_if_t::value, constexpr uint64_t ONE_FULL_BLOCK_OF_SECONDS_ONLY{LEAST_COMMON_MULTIPLE >> NUMBER_OF_BITS_IN_UINT32}; constexpr uint64_t SECONDS_PER_FULL_BLOCK{LEAST_COMMON_MULTIPLE / NANOSECS_PER_SEC}; - uint64_t multiplicatorHigh{static_cast(multiplicator >> NUMBER_OF_BITS_IN_UINT32)}; - uint64_t nanosecondsFromHigh{m_nanoseconds * multiplicatorHigh}; - uint64_t fullBlocksOfSecondsOnly{nanosecondsFromHigh / ONE_FULL_BLOCK_OF_SECONDS_ONLY}; - uint64_t remainingBlockWithFullAndFractionalSeconds{nanosecondsFromHigh % ONE_FULL_BLOCK_OF_SECONDS_ONLY}; + const uint64_t multiplicatorHigh{static_cast(multiplicator >> NUMBER_OF_BITS_IN_UINT32)}; + const uint64_t nanosecondsFromHigh{m_nanoseconds * multiplicatorHigh}; + const uint64_t fullBlocksOfSecondsOnly{nanosecondsFromHigh / ONE_FULL_BLOCK_OF_SECONDS_ONLY}; + const uint64_t remainingBlockWithFullAndFractionalSeconds{nanosecondsFromHigh % ONE_FULL_BLOCK_OF_SECONDS_ONLY}; - auto durationFromNanosecondsHigh = + // AXIVION Next Construct AutosarC++19_03-A4.7.1, AutosarC++19_03-M0.3.1, FaultDetection-IntegerOverflow : The logic from above prevents overflows + const auto durationFromNanosecondsHigh = Duration{fullBlocksOfSecondsOnly * SECONDS_PER_FULL_BLOCK, 0U} + Duration::fromNanoseconds(remainingBlockWithFullAndFractionalSeconds << NUMBER_OF_BITS_IN_UINT32); @@ -433,11 +438,15 @@ template inline constexpr Duration Duration::multiplyWith(const std::enable_if_t::value, T>& rhs) const noexcept { - // operator*(...) takes care of negative values for rhs - if (std::isnan(rhs)) { - return Duration::max(); + return (*this == Duration::zero()) ? Duration::zero() : Duration::max(); + } + + // this must be done after the NAN check in order to prevent to access a signaling NAN + if ((rhs <= static_cast(0)) || (*this == Duration::zero())) + { + return Duration::zero(); } auto durationFromSeconds = fromFloatingPointSeconds(static_cast(m_seconds) * rhs); @@ -458,15 +467,10 @@ Duration::multiplyWith(const std::enable_if_t::value, } template -inline constexpr Duration Duration::operator*(const T& rhs) const noexcept +inline constexpr Duration Duration::operator*(const T rhs) const noexcept { static_assert(std::is_arithmetic::value, "non arithmetic types are not supported for multiplication"); - if ((rhs <= static_cast(0)) || (*this == Duration::zero())) - { - return Duration::zero(); - } - return multiplyWith(rhs); } @@ -478,39 +482,39 @@ inline constexpr Duration operator*(const T& lhs, const Duration& rhs) noexcept } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Each argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words constexpr bool operator==(const Duration& lhs, const Duration& rhs) noexcept { return (lhs.m_seconds == rhs.m_seconds) && (lhs.m_nanoseconds == rhs.m_nanoseconds); } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Each argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words constexpr bool operator!=(const Duration& lhs, const Duration& rhs) noexcept { return !(lhs == rhs); } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Each argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words constexpr bool operator<(const Duration& lhs, const Duration& rhs) noexcept { return (lhs.m_seconds < rhs.m_seconds) || ((lhs.m_seconds == rhs.m_seconds) && (lhs.m_nanoseconds < rhs.m_nanoseconds)); } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Each argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words constexpr bool operator>(const Duration& lhs, const Duration& rhs) noexcept { return (lhs.m_seconds > rhs.m_seconds) || ((lhs.m_seconds == rhs.m_seconds) && (lhs.m_nanoseconds > rhs.m_nanoseconds)); } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Each argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words constexpr bool operator<=(const Duration& lhs, const Duration& rhs) noexcept { return !(lhs > rhs); } -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Each argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words constexpr bool operator>=(const Duration& lhs, const Duration& rhs) noexcept { return !(lhs < rhs); @@ -518,43 +522,43 @@ constexpr bool operator>=(const Duration& lhs, const Duration& rhs) noexcept namespace duration_literals { -// AXIVION Next Line AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard +// AXIVION Next Construct AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard inline constexpr Duration operator"" _ns(unsigned long long int value) noexcept { return Duration::fromNanoseconds(value); } -// AXIVION Next Line AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard +// AXIVION Next Construct AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard inline constexpr Duration operator"" _us(unsigned long long int value) noexcept { return Duration::fromMicroseconds(value); } -// AXIVION Next Line AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard +// AXIVION Next Construct AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard inline constexpr Duration operator"" _ms(unsigned long long int value) noexcept { return Duration::fromMilliseconds(value); } -// AXIVION Next Line AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard +// AXIVION Next Construct AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard inline constexpr Duration operator"" _s(unsigned long long int value) noexcept { return Duration::fromSeconds(value); } -// AXIVION Next Line AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard +// AXIVION Next Construct AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard inline constexpr Duration operator"" _m(unsigned long long int value) noexcept { return Duration::fromMinutes(value); } -// AXIVION Next Line AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard +// AXIVION Next Construct AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard inline constexpr Duration operator"" _h(unsigned long long int value) noexcept { return Duration::fromHours(value); } -// AXIVION Next Line AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard +// AXIVION Next Construct AutosarC++19_03-A3.9.1 : Use of unsigned long long int in user-defined literals is enforced by the standard inline constexpr Duration operator"" _d(unsigned long long int value) noexcept { return Duration::fromDays(value); diff --git a/iceoryx_hoofs/time/include/iox/duration.hpp b/iceoryx_hoofs/time/include/iox/duration.hpp index c8292fbf44..d260a11ece 100644 --- a/iceoryx_hoofs/time/include/iox/duration.hpp +++ b/iceoryx_hoofs/time/include/iox/duration.hpp @@ -198,30 +198,26 @@ class Duration // BEGIN ARITHMETIC - /// @brief Creates Duration object by addition. On overflow duration - /// saturates to Duration::max(). + /// @brief Creates Duration object by addition. On overflow duration saturates to Duration::max(). /// @param[in] rhs is the second summand /// @return a new Duration object // AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words constexpr Duration operator+(const Duration& rhs) const noexcept; - /// @brief Creates Duration object by addition. On overflow duration - /// saturates to Duration::max(). + /// @brief Adds a Duration to itself. On overflow duration saturates to Duration::max(). /// @param[in] rhs is the second summand /// @return a new Duration object // AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words constexpr Duration& operator+=(const Duration& rhs) noexcept; - /// @brief Creates Duration object by subtraction. On underflow duration - /// saturates to Duration::zero(). + /// @brief Creates Duration object by subtraction. On underflow duration saturates to Duration::zero(). /// @param[in] rhs is the subtrahend /// @return a new Duration object /// @attention Since negative durations are not allowed, the duration will be clamped to 0 // AXIVION Next Line AutosarC++19_03-A8.4.7 : Each argument is larger than two words constexpr Duration operator-(const Duration& rhs) const noexcept; - /// @brief Creates Duration object by subtraction. On underflow duration - /// saturates to Duration::zero(). + /// @brief Subtracts a Duration from itself. On underflow duration saturates to Duration::zero(). /// @param[in] rhs is the subtrahend /// @return a new Duration object /// @attention Since negative durations are not allowed, the duration will be clamped to 0 @@ -237,8 +233,9 @@ class Duration /// @note There is no explicit division operator! This can be achieved by multiplication with the inverse of the /// divisor. /// @note Multiplication of a non-zero duration with NaN and +Inf results in a saturated max duration + // AXIVION Next Construct AutosarC++19_03-M5.17.1 : Self assignment with 'operator*=' is not supported for now template - constexpr Duration operator*(const T& rhs) const noexcept; + constexpr Duration operator*(const T rhs) const noexcept; // END ARITHMETIC @@ -301,8 +298,7 @@ class Duration template friend constexpr Duration operator*(const T& lhs, const Duration& rhs) noexcept; - // AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words - friend std::ostream& operator<<(std::ostream& stream, const Duration& t) noexcept; + friend std::ostream& operator<<(std::ostream& stream, const Duration t); friend iox::log::LogStream& operator<<(iox::log::LogStream& stream, const Duration t) noexcept; static constexpr uint32_t SECS_PER_MINUTE{60U}; @@ -358,12 +354,13 @@ class Duration /// @return a new Duration object /// @attention Since negative durations are not allowed, the duration will be clamped to 0 // AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words +// AXIVION Next Construct AutosarC++19_03-M5.17.1 : Assigning the result of a Duration multiplication with 'operator*=' to an arithmetic type is not supported template constexpr Duration operator*(const T& lhs, const Duration& rhs) noexcept; /// @brief stream operator for the Duration class // AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words -std::ostream& operator<<(std::ostream& stream, const Duration& t) noexcept; +std::ostream& operator<<(std::ostream& stream, const Duration t); /// @brief Equal to operator /// @param[in] lhs is the left hand side of the comparison diff --git a/iceoryx_hoofs/time/source/duration.cpp b/iceoryx_hoofs/time/source/duration.cpp index b609f456c9..08f14258b0 100644 --- a/iceoryx_hoofs/time/source/duration.cpp +++ b/iceoryx_hoofs/time/source/duration.cpp @@ -30,6 +30,7 @@ struct timespec Duration::timespec(const TimeSpecReference reference) const noex using SEC_TYPE = decltype(std::declval().tv_sec); using NSEC_TYPE = decltype(std::declval().tv_nsec); + // AXIVION Next Construct AutosarC++19_03-M0.1.2, AutosarC++19_03-M0.1.9, FaultDetection-DeadBranches : False positive! Branching depends on input parameter if (reference == TimeSpecReference::None) { static_assert(sizeof(uint64_t) >= sizeof(SEC_TYPE), "casting might alter result"); @@ -39,13 +40,16 @@ struct timespec Duration::timespec(const TimeSpecReference reference) const noex return {std::numeric_limits::max(), NANOSECS_PER_SEC - 1U}; } - auto tv_sec = static_cast(this->m_seconds); - auto tv_nsec = static_cast(this->m_nanoseconds); + const auto tv_sec = static_cast(this->m_seconds); + const auto tv_nsec = static_cast(this->m_nanoseconds); return {tv_sec, tv_nsec}; } - struct timespec referenceTime = {}; + struct timespec referenceTime + { + }; + // AXIVION Next Construct AutosarC++19_03-M0.1.2, AutosarC++19_03-M0.1.9, FaultDetection-DeadBranches : False positive! Branching depends on input parameter if (posix::posixCall(clock_gettime)((reference == TimeSpecReference::Epoch) ? CLOCK_REALTIME : CLOCK_MONOTONIC, &referenceTime) .failureReturnValue(-1) @@ -55,7 +59,7 @@ struct timespec Duration::timespec(const TimeSpecReference reference) const noex return {0, 0}; } - auto targetTime = Duration(referenceTime) + *this; + const auto targetTime = Duration(referenceTime) + *this; static_assert(sizeof(uint64_t) >= sizeof(SEC_TYPE), "casting might alter result"); if (targetTime.m_seconds > static_cast(std::numeric_limits::max())) @@ -64,17 +68,19 @@ struct timespec Duration::timespec(const TimeSpecReference reference) const noex return {std::numeric_limits::max(), NANOSECS_PER_SEC - 1U}; } - auto tv_sec = static_cast(targetTime.m_seconds); - auto tv_nsec = static_cast(targetTime.m_nanoseconds); + const auto tv_sec = static_cast(targetTime.m_seconds); + const auto tv_nsec = static_cast(targetTime.m_nanoseconds); return {tv_sec, tv_nsec}; } -std::ostream& operator<<(std::ostream& stream, const units::Duration& t) noexcept +// AXIVION Next Construct AutosarC++19_03-M5.17.1 : This is not used as shift operator but as stream operator and does not require to implement '<<=' +std::ostream& operator<<(std::ostream& stream, const units::Duration t) { stream << t.m_seconds << "s " << t.m_nanoseconds << "ns"; return stream; } +// AXIVION Next Construct AutosarC++19_03-M5.17.1 : This is not used as shift operator but as stream operator and does not require to implement '<<=' iox::log::LogStream& operator<<(iox::log::LogStream& stream, const Duration t) noexcept { stream << t.m_seconds << "s " << t.m_nanoseconds << "ns"; From 274c88776a3709d6a1ac56c6e122dccde5341a9e Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Tue, 14 Feb 2023 20:30:31 +0100 Subject: [PATCH 07/13] iox-#1394 Use address operator to pass function pointer to PosixCallBuilder --- .../include/iceoryx_hoofs/posix_wrapper/posix_call.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/posix_call.hpp b/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/posix_call.hpp index c79236d3be..7bcb0169d0 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/posix_call.hpp +++ b/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/posix_call.hpp @@ -107,7 +107,7 @@ struct PosixCallDetails /// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define posixCall(f) \ internal::createPosixCallBuilder( \ - f, \ + &(f), \ (#f), \ __FILE__, \ __LINE__, \ From 23e76a4c13be88bbc960e1a5509cdc427271d1cc Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Tue, 14 Feb 2023 20:43:03 +0100 Subject: [PATCH 08/13] iox-#1394 Fix Axivion warnigs for 'into' --- .../include/iceoryx_dust/cxx/std_string_support.hpp | 2 +- .../iceoryx_dust/internal/cxx/std_string_support.inl | 2 +- iceoryx_hoofs/test/moduletests/test_utility_into.cpp | 2 +- iceoryx_hoofs/utility/include/iox/detail/into.inl | 7 ++++--- iceoryx_hoofs/utility/include/iox/into.hpp | 6 +++--- .../internal/popo/building_blocks/chunk_sender.hpp | 2 +- .../internal/popo/building_blocks/chunk_sender.inl | 2 +- .../iceoryx_posh/internal/popo/ports/server_port_user.hpp | 2 +- .../iceoryx_posh/internal/popo/ports/server_port_user.inl | 2 +- 9 files changed, 14 insertions(+), 13 deletions(-) diff --git a/iceoryx_dust/include/iceoryx_dust/cxx/std_string_support.hpp b/iceoryx_dust/include/iceoryx_dust/cxx/std_string_support.hpp index 8689aee82f..1b93cb1aba 100644 --- a/iceoryx_dust/include/iceoryx_dust/cxx/std_string_support.hpp +++ b/iceoryx_dust/include/iceoryx_dust/cxx/std_string_support.hpp @@ -26,7 +26,7 @@ namespace iox template struct FromImpl, std::string> { - static std::string fromImpl(const string& value); + static std::string fromImpl(const string& value) noexcept; }; template diff --git a/iceoryx_dust/include/iceoryx_dust/internal/cxx/std_string_support.inl b/iceoryx_dust/include/iceoryx_dust/internal/cxx/std_string_support.inl index 7ebc22e9c1..c4e836093a 100644 --- a/iceoryx_dust/include/iceoryx_dust/internal/cxx/std_string_support.inl +++ b/iceoryx_dust/include/iceoryx_dust/internal/cxx/std_string_support.inl @@ -21,7 +21,7 @@ namespace iox { template -inline std::string FromImpl, std::string>::fromImpl(const string& value) +inline std::string FromImpl, std::string>::fromImpl(const string& value) noexcept { return std::string(value.c_str(), value.size()); } diff --git a/iceoryx_hoofs/test/moduletests/test_utility_into.cpp b/iceoryx_hoofs/test/moduletests/test_utility_into.cpp index 0c81c3ed2c..ea4c866d98 100644 --- a/iceoryx_hoofs/test/moduletests/test_utility_into.cpp +++ b/iceoryx_hoofs/test/moduletests/test_utility_into.cpp @@ -36,7 +36,7 @@ enum class B namespace iox { template <> -constexpr B from(A e) +constexpr B from(A e) noexcept { switch (e) { diff --git a/iceoryx_hoofs/utility/include/iox/detail/into.inl b/iceoryx_hoofs/utility/include/iox/detail/into.inl index 7387abf10b..9922fee0f0 100644 --- a/iceoryx_hoofs/utility/include/iox/detail/into.inl +++ b/iceoryx_hoofs/utility/include/iox/detail/into.inl @@ -23,13 +23,14 @@ namespace iox { template -inline constexpr typename detail::extract_into_type::type_t from(const SourceType value) +inline constexpr typename detail::extract_into_type::type_t from(const SourceType value) noexcept { return FromImpl::fromImpl(value); } +// AXIVION Next Construct AutosarC++19_03-A7.1.5 : 'auto' is only used for the generic implementation which will always result in a compile error template -inline auto FromImpl::fromImpl(const SourceType&) +inline auto FromImpl::fromImpl(const SourceType&) noexcept { static_assert(cxx::always_false_v && cxx::always_false_v, "\n \ Conversion for the specified types is not implemented!\n \ @@ -41,7 +42,7 @@ inline auto FromImpl::fromImpl(const SourceType&) } template -inline constexpr typename detail::extract_into_type::type_t into(const SourceType value) +inline constexpr typename detail::extract_into_type::type_t into(const SourceType value) noexcept { return from(value); } diff --git a/iceoryx_hoofs/utility/include/iox/into.hpp b/iceoryx_hoofs/utility/include/iox/into.hpp index 9b12970aae..9fb49539cf 100644 --- a/iceoryx_hoofs/utility/include/iox/into.hpp +++ b/iceoryx_hoofs/utility/include/iox/into.hpp @@ -94,14 +94,14 @@ struct extract_into_type> /// @param[in] value of type SourceType to convert to DestinationType /// @return converted value of SourceType to corresponding value of DestinationType template -constexpr typename detail::extract_into_type::type_t from(const SourceType value); +constexpr typename detail::extract_into_type::type_t from(const SourceType value) noexcept; // Using a struct as impl, as free functions do not support partially specialized templates template struct FromImpl { - static auto fromImpl(const SourceType& value); + static auto fromImpl(const SourceType& value) noexcept; }; /// @brief Converts a value of type SourceType to a corresponding value of type DestinationType. This is a convenience @@ -115,7 +115,7 @@ struct FromImpl /// @param[in] value of type SourceType to convert to DestinationType /// @return converted value of SourceType to corresponding value of DestinationType template -constexpr typename detail::extract_into_type::type_t into(const SourceType value); +constexpr typename detail::extract_into_type::type_t into(const SourceType value) noexcept; } // namespace iox diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_sender.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_sender.hpp index c513c3141f..c07441d464 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_sender.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_sender.hpp @@ -46,7 +46,7 @@ enum class AllocationError template <> constexpr popo::AllocationError -from(const mepoo::MemoryManager::Error error); +from(const mepoo::MemoryManager::Error error) noexcept; namespace popo { diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_sender.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_sender.inl index 000cbd01ee..18390eeab6 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_sender.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/building_blocks/chunk_sender.inl @@ -25,7 +25,7 @@ namespace iox template <> constexpr popo::AllocationError -from(const mepoo::MemoryManager::Error error) +from(const mepoo::MemoryManager::Error error) noexcept { switch (error) { diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/server_port_user.hpp b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/server_port_user.hpp index 897ea4d300..1a32412e18 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/server_port_user.hpp +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/server_port_user.hpp @@ -60,7 +60,7 @@ inline log::LogStream& operator<<(log::LogStream& stream, ServerRequestResult va template <> constexpr popo::ServerRequestResult -from(const popo::ChunkReceiveResult value); +from(const popo::ChunkReceiveResult value) noexcept; namespace popo { diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/server_port_user.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/server_port_user.inl index 6ffe4f5564..847f5802f6 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/server_port_user.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/ports/server_port_user.inl @@ -23,7 +23,7 @@ namespace iox { template <> constexpr popo::ServerRequestResult -from(const popo::ChunkReceiveResult value) +from(const popo::ChunkReceiveResult value) noexcept { switch (value) { From d49265d0323fa11f5a469d0cd745daefbd0cd303 Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Tue, 14 Feb 2023 20:58:56 +0100 Subject: [PATCH 09/13] iox-#1394 Fix Axivion warnigs in algorithm --- iceoryx_hoofs/include/iceoryx_hoofs/cxx/algorithm.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/cxx/algorithm.hpp b/iceoryx_hoofs/include/iceoryx_hoofs/cxx/algorithm.hpp index 314f18e401..371358a0b9 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/cxx/algorithm.hpp +++ b/iceoryx_hoofs/include/iceoryx_hoofs/cxx/algorithm.hpp @@ -195,6 +195,7 @@ struct range range(T t) noexcept : m_value(t) { + // AXIVION Next Construct AutosarC++19_03-A1.4.3 : False positive! 't >= Minimum' depends on input parameter cxx::Expects((t >= Minimum) && (t <= Maximum)); } @@ -216,7 +217,8 @@ template constexpr bool isPowerOfTwo(const T n) noexcept { static_assert(std::is_unsigned::value && !std::is_same::value, "Only unsigned integer are allowed!"); - return n && ((n & (n - 1U)) == 0U); + // AXIVION Next Construct AutosarC++19_03-M0.1.2, AutosarC++19_03-M0.1.9, FaultDetection-DeadBranches : False positive! 'n' can be zero. + return (n > 0) && ((n & (n - 1U)) == 0U); } } // namespace iox From 0a9b591ce58d17d09c6884c7a0bda09f0bd94df5 Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Tue, 14 Feb 2023 20:59:11 +0100 Subject: [PATCH 10/13] iox-#1394 Fix Axivion warnigs in attributes --- iceoryx_hoofs/include/iceoryx_hoofs/cxx/attributes.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/cxx/attributes.hpp b/iceoryx_hoofs/include/iceoryx_hoofs/cxx/attributes.hpp index fe53bba0f6..002aa8de06 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/cxx/attributes.hpp +++ b/iceoryx_hoofs/include/iceoryx_hoofs/cxx/attributes.hpp @@ -29,6 +29,7 @@ namespace internal /// compiler an unused variable. "static_cast" produces an useless-cast warning /// on gcc and this approach solves it cleanly. template +// AXIVION Next Construct AutosarC++19_03-M0.1.8 : No side effects are the intended behavior of the function inline void IOX_DISCARD_RESULT_IMPL(T&&) noexcept { } From ed38a3bb3bb54e8e490d8f4193627dacc686685b Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Wed, 15 Feb 2023 13:46:59 +0100 Subject: [PATCH 11/13] iox-#1394 Remove superfluous suppression --- iceoryx_hoofs/time/include/iox/duration.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/iceoryx_hoofs/time/include/iox/duration.hpp b/iceoryx_hoofs/time/include/iox/duration.hpp index d260a11ece..7ff3921f86 100644 --- a/iceoryx_hoofs/time/include/iox/duration.hpp +++ b/iceoryx_hoofs/time/include/iox/duration.hpp @@ -359,7 +359,6 @@ template constexpr Duration operator*(const T& lhs, const Duration& rhs) noexcept; /// @brief stream operator for the Duration class -// AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words std::ostream& operator<<(std::ostream& stream, const Duration t); /// @brief Equal to operator From e98a120a6d65a9a7b2c654dce429f53b92ddbb72 Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Wed, 15 Feb 2023 17:12:56 +0100 Subject: [PATCH 12/13] iox-#1394 Dummy implementation with static_assert for 'operator*=' with assignment to the arithmetic type --- iceoryx_hoofs/time/include/iox/detail/duration.inl | 9 +++++++++ iceoryx_hoofs/time/include/iox/duration.hpp | 8 +++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/iceoryx_hoofs/time/include/iox/detail/duration.inl b/iceoryx_hoofs/time/include/iox/detail/duration.inl index 2ea9125d35..373744db45 100644 --- a/iceoryx_hoofs/time/include/iox/detail/duration.inl +++ b/iceoryx_hoofs/time/include/iox/detail/duration.inl @@ -481,6 +481,15 @@ inline constexpr Duration operator*(const T& lhs, const Duration& rhs) noexcept return rhs * lhs; } +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words +template +inline constexpr T& operator*=(const T&, const Duration&) noexcept +{ + static_assert( + cxx::always_false_v, + "Assigning the result of a Duration multiplication with 'operator*=' to an arithmetic type is not supported"); + return T(); +} // AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words constexpr bool operator==(const Duration& lhs, const Duration& rhs) noexcept diff --git a/iceoryx_hoofs/time/include/iox/duration.hpp b/iceoryx_hoofs/time/include/iox/duration.hpp index 7ff3921f86..d09bd2b831 100644 --- a/iceoryx_hoofs/time/include/iox/duration.hpp +++ b/iceoryx_hoofs/time/include/iox/duration.hpp @@ -17,6 +17,7 @@ #ifndef IOX_HOOFS_TIME_UNITS_DURATION_HPP #define IOX_HOOFS_TIME_UNITS_DURATION_HPP +#include "iceoryx_hoofs/cxx/type_traits.hpp" #include "iceoryx_hoofs/log/logging.hpp" #include "iceoryx_hoofs/log/logstream.hpp" #include "iceoryx_platform/time.hpp" // required for QNX @@ -354,10 +355,15 @@ class Duration /// @return a new Duration object /// @attention Since negative durations are not allowed, the duration will be clamped to 0 // AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words -// AXIVION Next Construct AutosarC++19_03-M5.17.1 : Assigning the result of a Duration multiplication with 'operator*=' to an arithmetic type is not supported template constexpr Duration operator*(const T& lhs, const Duration& rhs) noexcept; +/// @brief Dummy implementation with a static assert. Assigning the result of a Duration +/// multiplication with 'operator*=' to an arithmetic type is not supported +// AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words +template +constexpr T& operator*=(const T& lhs, const Duration& rhs) noexcept; + /// @brief stream operator for the Duration class std::ostream& operator<<(std::ostream& stream, const Duration t); From 19784fa68bfb08b1ca17e92a07efeada33c0a2ae Mon Sep 17 00:00:00 2001 From: Mathias Kraus Date: Wed, 15 Feb 2023 17:34:05 +0100 Subject: [PATCH 13/13] iox-#1394 Implement 'operator*=' with assignment to the 'Duration' --- .../moduletests/test_time_unit_duration.cpp | 12 ++++++++++++ .../time/include/iox/detail/duration.inl | 10 ++++++++++ iceoryx_hoofs/time/include/iox/duration.hpp | 17 ++++++++++++++--- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/iceoryx_hoofs/test/moduletests/test_time_unit_duration.cpp b/iceoryx_hoofs/test/moduletests/test_time_unit_duration.cpp index bd1473e226..b8163fe7f1 100644 --- a/iceoryx_hoofs/test/moduletests/test_time_unit_duration.cpp +++ b/iceoryx_hoofs/test/moduletests/test_time_unit_duration.cpp @@ -2072,6 +2072,18 @@ TEST(Duration_test, MultiplyDurationMoreThanOneSecondWithFloatResultsInMoreThanO multiply(duration, MULTIPLICATOR, EXPECTED_DURATION); } +TEST(Duration_test, MultiplyDurationWithSelfAssignOperatorWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "ac7e2f7e-984b-4aca-a472-9dc1f1c1f30c"); + constexpr int64_t MULTIPLICATOR{3}; + constexpr Duration EXPECTED_DURATION{6_s + 36_ns}; + auto duration = 2_s + 12_ns; + + duration *= MULTIPLICATOR; + + EXPECT_THAT(duration, Eq(EXPECTED_DURATION)); +} + TEST(Duration_test, MultiplyDurationWithFractionalFloat) { ::testing::Test::RecordProperty("TEST_ID", "3adcaec4-06fb-4ae5-a05b-70764fc00d64"); diff --git a/iceoryx_hoofs/time/include/iox/detail/duration.inl b/iceoryx_hoofs/time/include/iox/detail/duration.inl index 373744db45..0dc4432f21 100644 --- a/iceoryx_hoofs/time/include/iox/detail/duration.inl +++ b/iceoryx_hoofs/time/include/iox/detail/duration.inl @@ -474,6 +474,16 @@ inline constexpr Duration Duration::operator*(const T rhs) const noexcept return multiplyWith(rhs); } +template +inline constexpr Duration& Duration::operator*=(const T rhs) noexcept +{ + static_assert(std::is_arithmetic::value, "non arithmetic types are not supported for multiplication"); + + *this = multiplyWith(rhs); + + return *this; +} + // AXIVION Next Construct AutosarC++19_03-A8.4.7 : Each argument is larger than two words template inline constexpr Duration operator*(const T& lhs, const Duration& rhs) noexcept diff --git a/iceoryx_hoofs/time/include/iox/duration.hpp b/iceoryx_hoofs/time/include/iox/duration.hpp index d09bd2b831..d85c223eb0 100644 --- a/iceoryx_hoofs/time/include/iox/duration.hpp +++ b/iceoryx_hoofs/time/include/iox/duration.hpp @@ -207,7 +207,7 @@ class Duration /// @brief Adds a Duration to itself. On overflow duration saturates to Duration::max(). /// @param[in] rhs is the second summand - /// @return a new Duration object + /// @return a reference to itself // AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words constexpr Duration& operator+=(const Duration& rhs) noexcept; @@ -220,7 +220,7 @@ class Duration /// @brief Subtracts a Duration from itself. On underflow duration saturates to Duration::zero(). /// @param[in] rhs is the subtrahend - /// @return a new Duration object + /// @return a reference to itself /// @attention Since negative durations are not allowed, the duration will be clamped to 0 // AXIVION Next Line AutosarC++19_03-A8.4.7 : Argument is larger than two words constexpr Duration& operator-=(const Duration& rhs) noexcept; @@ -234,10 +234,21 @@ class Duration /// @note There is no explicit division operator! This can be achieved by multiplication with the inverse of the /// divisor. /// @note Multiplication of a non-zero duration with NaN and +Inf results in a saturated max duration - // AXIVION Next Construct AutosarC++19_03-M5.17.1 : Self assignment with 'operator*=' is not supported for now template constexpr Duration operator*(const T rhs) const noexcept; + /// @brief Multiplies a Duration with an arithmetic type and assigns the result to itself. + /// @tparam T is an arithmetic type for the multiplicator + /// @param[in] rhs is the multiplicator + /// @return a reference to itself + /// @attention Since negative durations are not allowed, the duration will be clamped to 0 + /// @note A duration of 0 will always result in 0, no matter if multiplied with NaN or +Inf + /// @note There is no explicit division operator! This can be achieved by multiplication with the inverse of the + /// divisor. + /// @note Multiplication of a non-zero duration with NaN and +Inf results in a saturated max duration + template + constexpr Duration& operator*=(const T rhs) noexcept; + // END ARITHMETIC // BEGIN CONVERSION