Re: [PATCH] asm-generic: avoid sparse {get,put}_unaligned warning
From: Arnd Bergmann <arnd@arndb.de>
Date: 2021-07-26 16:38:31
Also in:
batman, lkml
Subsystem:
generic include/asm header files, the rest · Maintainers:
Arnd Bergmann, Linus Torvalds
On Mon, Jul 26, 2021 at 5:04 PM Sven Eckelmann [off-list ref] wrote:
On Monday, 26 July 2021 14:57:31 CEST Arnd Bergmann wrote:quoted
quoted
quoted
The special attribute force must be used in such statements when the cast is known to be safe to avoid these warnings.I can see why this would warn, but I'm having trouble reproducing the warning on linux-next.I have sparse 0.6.3 on an Debian bullseye amd64 system. Sources are from linux-next next-20210723 make allnoconfig cat >> .config << "EOF" CONFIG_NET=y CONFIG_INET=y CONFIG_BATMAN_ADV=y CONFIG_BATMAN_ADV_DAT=y EOF make olddefconfig make CHECK="sparse -Wbitwise-pointer" C=1 I should maybe have made this clearer in the last sentence of the first paragraph: "This is also true for pointers to variables with this type when -Wbitwise-pointer is activated."
Ok, got it. I assumed this would be turned on by an 'allmodconfig' build.
quoted
If both work equally well, I'd prefer Sven's patch since that only expands 'type' once, while container_of() expands it three more times
Not sure what I was thinking here, as it's not 'type' that gets expanded here but 'ptr'. We could do Al's suggestion to avoid the __force without multiple expansions, using
diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h
index 1c4242416c9f..d138dc5fd8e3 100644
--- a/include/asm-generic/unaligned.h
+++ b/include/asm-generic/unaligned.h@@ -10,17 +10,25 @@ #include <asm/byteorder.h> #define __get_unaligned_t(type, ptr) ({ \ - const struct { type x; } __packed *__pptr =
(typeof(__pptr))(ptr); \
+ const struct { type x; } __packed *__pptr =
\
+ container_of(ptr, typeof(*__pptr), x);
\
__pptr->x;
\
})
#define __put_unaligned_t(type, val, ptr) do {
\
- struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr);
\
+ struct { type x; } __packed *__pptr =
\
+ container_of(ptr, typeof(*__pptr), x);
\
__pptr->x = (val);
\
} while (0)
-#define get_unaligned(ptr) __get_unaligned_t(typeof(*(ptr)), (ptr))
-#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
+#define get_unaligned(ptr) ({
\
+ __auto_type _ptr = (ptr);
\
+ __get_unaligned_t(typeof(*(_ptr)), (_ptr));
\
+})
+#define put_unaligned(val, ptr) ({
\
+ __auto_type _ptr = (ptr);
\
+ __put_unaligned_t(typeof(*(_ptr)), (val), (_ptr));
\
+})
static inline u16 get_unaligned_le16(const void *p)
{
Not sure if this is any better.
Arnd