[PATCH v2 0/2] Fix truncation warnings from building test_scanf.c

STALE1895d

Revision v2 of 3 in this series.

3 messages, 1 author, 2021-05-25 · open the first message on its own page

[PATCH v2 0/2] Fix truncation warnings from building test_scanf.c

From: Richard Fitzgerald <rf@opensource.cirrus.com>
Date: 2021-05-25 12:21:16

The kernel test robot is reporting truncation warnings when building
lib/test_scanf.c:

1) lib/test_scanf.c:250:9: sparse: sparse: cast truncates bits from
   constant value (ffff0001 becomes 1)
   Reported on several lines.

2) include/linux/prandom.h:114:45: sparse: sparse: cast truncates bits
   from constant value (4f2e5357408c3c09 becomes 408c3c09)

(1) is caused by test_scanf.c using type_min() on an unsigned type. The
truncation is expected but the use of type_min() on an unsigned is
unnecessary because we know it is always 0.

(2) is caused by prandom_seed_state() storing a modified u64 seed value
into a u32 - sparse will warn that this causes a truncation. 

The two patches in this series fix these problems.

Richard Fitzgerald (2):
  lib: test_scanf: Remove pointless use of type_min() with unsigned
    types
  random32: Fix implicit truncation warning in prandom_seed_state()

 include/linux/prandom.h |  2 +-
 lib/test_scanf.c        | 13 ++++++-------
 2 files changed, 7 insertions(+), 8 deletions(-)

-- 
2.20.1

[PATCH v2 2/2] random32: Fix implicit truncation warning in prandom_seed_state()

From: Richard Fitzgerald <rf@opensource.cirrus.com>
Date: 2021-05-25 12:21:20

sparse generates the following warning:

 include/linux/prandom.h:114:45: sparse: sparse: cast truncates bits from
 constant value

This is because the 64-bit seed value is manipulated and then placed in a
u32, causing an implicit cast and truncation. A forced cast to u32 doesn't
prevent this warning, which is reasonable because a typecast doesn't prove
that truncation was expected.

Logical-AND the value with 0xffffffff to make explicit that truncation to
32-bit is intended.

Reported-by: kernel test robot <redacted>
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
 include/linux/prandom.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/prandom.h b/include/linux/prandom.h
index bbf4b4ad61df..056d31317e49 100644
--- a/include/linux/prandom.h
+++ b/include/linux/prandom.h
@@ -111,7 +111,7 @@ static inline u32 __seed(u32 x, u32 m)
  */
 static inline void prandom_seed_state(struct rnd_state *state, u64 seed)
 {
-	u32 i = (seed >> 32) ^ (seed << 10) ^ seed;
+	u32 i = ((seed >> 32) ^ (seed << 10) ^ seed) & 0xffffffffUL;
 
 	state->s1 = __seed(i,   2U);
 	state->s2 = __seed(i,   8U);
-- 
2.20.1

[PATCH v2 1/2] lib: test_scanf: Remove pointless use of type_min() with unsigned types

From: Richard Fitzgerald <rf@opensource.cirrus.com>
Date: 2021-05-25 12:21:59

sparse was producing warnings of the form:

 sparse: cast truncates bits from constant value (ffff0001 becomes 1)

There is no actual problem here. Using type_min() on an unsigned type
results in an (expected) truncation.

However, there is no need to test an unsigned value against type_min().
The minimum value of an unsigned is obviously 0, and any value cast to
an unsigned type is >= 0, so for unsigneds only type_max() need be tested.

This patch also takes the opportunity to clean up the implementation of
simple_numbers_loop() to use a common pattern for the positive and
negative test.

Reported-by: kernel test robot <redacted>
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
 lib/test_scanf.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/lib/test_scanf.c b/lib/test_scanf.c
index 8d577aec6c28..48ff5747a4da 100644
--- a/lib/test_scanf.c
+++ b/lib/test_scanf.c
@@ -187,8 +187,8 @@ static const unsigned long long numbers[] __initconst = {
 #define value_representable_in_type(T, val)					 \
 (is_signed_type(T)								 \
 	? ((long long)(val) >= type_min(T)) && ((long long)(val) <= type_max(T)) \
-	: ((unsigned long long)(val) >= type_min(T)) &&				 \
-	  ((unsigned long long)(val) <= type_max(T)))
+	: ((unsigned long long)(val) <= type_max(T)))
+
 
 #define test_one_number(T, gen_fmt, scan_fmt, val, fn)			\
 do {									\
@@ -204,12 +204,11 @@ do {									\
 	int i;								\
 									\
 	for (i = 0; i < ARRAY_SIZE(numbers); i++) {			\
-		if (!value_representable_in_type(T, numbers[i]))	\
-			continue;					\
+		if (value_representable_in_type(T, numbers[i]))		\
+			test_one_number(T, gen_fmt, scan_fmt,		\
+					numbers[i], fn);		\
 									\
-		test_one_number(T, gen_fmt, scan_fmt, numbers[i], fn);	\
-									\
-		if (is_signed_type(T))					\
+		if (value_representable_in_type(T, -numbers[i]))	\
 			test_one_number(T, gen_fmt, scan_fmt,		\
 					-numbers[i], fn);		\
 	}								\
-- 
2.20.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help