diff options
author | Furquan Shaikh <furquan@google.com> | 2020-09-03 21:53:17 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-06-02 09:21:23 +0000 |
commit | 66ac38d38181360889d3133e4d41dc0ebca3554e (patch) | |
tree | f153d3161fe2b24b28323b849be8a32dc615ada2 | |
parent | f7b945264c001e700bebc66c6401ae67e97df74e (diff) | |
download | chrome-ec-66ac38d38181360889d3133e4d41dc0ebca3554e.tar.gz |
motion_sense: Fix signed/unsigned comparison in ec_motion_sensor_clamp_* helpers
ec_motion_sensor_clamp_* helpers are performing comparison between
signed and unsigned integers leading to non-compliant code. This
results in comparison operation converting negative values to unsigned
integers. Example: When ec_motion_sensor_clamp_i16() is called with a
value of -15000, it returns 32767 instead of -15000 because:
* MAX(-15000, INT16_MIN) ==> MAX(-15000, -32768) ==> -15000
* MIN(-15000, INT16_MAX) ==> MIN(-15000, 32767U) ==> This expands to:
int32_t temp_a = -15000;
uint32_t temp_b = 32767U; << This is my assumption what the compiler
would be doing
(temp_a < temp_b) ? temp_a : temp_b;
In this comparison, temp_a is signed int whereas temp_b is unsigned
int. As per C-standard for usual arithmetic conversions, for the
comparison operation, both operands are converted to unsigned integer
type corresponding to the type of the operand with signed integer
type.
Thus the comparison operation changes to comparison between:
-15000 --> 0xffffc568
32767 --> 0x7fff
and hence returns 0x7fff i.e. 32767.
This change adds explicit type cast for constant values passed into
MIN()/MAX() to ensure that the comparison is compliant to C
standard. With this the above comparison in
ec_motion_sensor_clamp_i16() correctly returns -15000.
BUG=b:167751183,b:189894836
BRANCH=zork
TEST=Verified that screen flips when in tablet mode on Morphius. Also,
verified using following steps that raw data seen in sysfs consists of
positive and negative values:
$ cd /sys/bus/iio/devices
$ watch -n 0.1 grep . */in_*_raw
Signed-off-by: Furquan Shaikh <furquan@google.com>
Change-Id: I444c9aeab4ae8a4726600222080fb141084b7a41
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2393459
Tested-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Commit-Queue: Denis Brockus <dbrockus@chromium.org>
Auto-Submit: Furquan Shaikh <furquan@chromium.org>
(cherry picked from commit ec743f4b565061208d33dfd36d8fd753197f998c)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2932464
Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
Commit-Queue: Gwendal Grignou <gwendal@chromium.org>
Tested-by: Gwendal Grignou <gwendal@chromium.org>
-rw-r--r-- | include/motion_sense.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/include/motion_sense.h b/include/motion_sense.h index 08e78bc75c..c340f6b916 100644 --- a/include/motion_sense.h +++ b/include/motion_sense.h @@ -301,7 +301,7 @@ enum motionsensor_orientation motion_sense_remap_orientation( */ static inline uint16_t ec_motion_sensor_clamp_u16(const int32_t value) { - return (uint16_t)MIN(MAX(value, 0), UINT16_MAX); + return (uint16_t)MIN(MAX(value, 0), (int32_t)UINT16_MAX); } static inline void ec_motion_sensor_clamp_u16s(uint16_t *arr, const int32_t *v) { @@ -312,7 +312,7 @@ static inline void ec_motion_sensor_clamp_u16s(uint16_t *arr, const int32_t *v) static inline int16_t ec_motion_sensor_clamp_i16(const int32_t value) { - return MIN(MAX(value, INT16_MIN), INT16_MAX); + return MIN(MAX(value, (int32_t)INT16_MIN), (int32_t)INT16_MAX); } static inline void ec_motion_sensor_clamp_i16s(int16_t *arr, const int32_t *v) { |