summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/base/sat_counter.hh23
-rw-r--r--src/base/sat_counter.test.cc39
2 files changed, 56 insertions, 6 deletions
diff --git a/src/base/sat_counter.hh b/src/base/sat_counter.hh
index 6aeca681d..946da4f26 100644
--- a/src/base/sat_counter.hh
+++ b/src/base/sat_counter.hh
@@ -44,6 +44,7 @@
#ifndef __BASE_SAT_COUNTER_HH__
#define __BASE_SAT_COUNTER_HH__
+#include <cassert>
#include <cstdint>
#include "base/logging.hh"
@@ -172,6 +173,7 @@ class SatCounter
SatCounter&
operator>>=(const int& shift)
{
+ assert(shift >= 0);
this->counter >>= shift;
return *this;
}
@@ -180,6 +182,7 @@ class SatCounter
SatCounter&
operator<<=(const int& shift)
{
+ assert(shift >= 0);
this->counter <<= shift;
if (this->counter > maxVal) {
this->counter = maxVal;
@@ -191,10 +194,14 @@ class SatCounter
SatCounter&
operator+=(const int& value)
{
- if (maxVal - this->counter >= value) {
- this->counter += value;
+ if (value >= 0) {
+ if (maxVal - this->counter >= value) {
+ this->counter += value;
+ } else {
+ this->counter = maxVal;
+ }
} else {
- this->counter = maxVal;
+ *this -= -value;
}
return *this;
}
@@ -203,10 +210,14 @@ class SatCounter
SatCounter&
operator-=(const int& value)
{
- if (this->counter > value) {
- this->counter -= value;
+ if (value >= 0) {
+ if (this->counter > value) {
+ this->counter -= value;
+ } else {
+ this->counter = 0;
+ }
} else {
- this->counter = 0;
+ *this += -value;
}
return *this;
}
diff --git a/src/base/sat_counter.test.cc b/src/base/sat_counter.test.cc
index 817f2c7ac..d9a377f9f 100644
--- a/src/base/sat_counter.test.cc
+++ b/src/base/sat_counter.test.cc
@@ -28,6 +28,7 @@
* Authors: Daniel Carvalho
*/
+#include <gtest/gtest-spi.h>
#include <gtest/gtest.h>
#include <utility>
@@ -184,6 +185,11 @@ TEST(SatCounterTest, Shift)
ASSERT_EQ(counter, value);
counter >>= saturated_counter;
ASSERT_EQ(counter, 0);
+
+ // Make sure the counters cannot be shifted by negative numbers, since
+ // that is undefined behaviour
+ ASSERT_DEATH(counter >>= -1, "");
+ ASSERT_DEATH(counter <<= -1, "");
}
/**
@@ -319,3 +325,36 @@ TEST(SatCounterTest, AddSubAssignment)
ASSERT_EQ(counter, 0);
}
+/**
+ * Test add-assignment and subtract assignment using negative numbers.
+ */
+TEST(SatCounterTest, NegativeAddSubAssignment)
+{
+ const unsigned bits = 3;
+ const unsigned max_value = (1 << bits) - 1;
+ SatCounter counter(bits, max_value);
+ int value = max_value;
+
+ // Test add-assignment for a few negative values until zero is reached
+ counter += -2;
+ value += -2;
+ ASSERT_EQ(counter, value);
+ counter += -3;
+ value += -3;
+ ASSERT_EQ(counter, value);
+ counter += (int)-max_value;
+ value = 0;
+ ASSERT_EQ(counter, value);
+
+ // Test subtract-assignment for a few negative values until saturation
+ counter -= -2;
+ value -= -2;
+ ASSERT_EQ(counter, value);
+ counter -= -3;
+ value -= -3;
+ ASSERT_EQ(counter, value);
+ counter -= (int)-max_value;
+ value = max_value;
+ ASSERT_EQ(counter, value);
+}
+