Skip to content

Commit

Permalink
saner typechecking in generic unaligned.h
Browse files Browse the repository at this point in the history
Verify that types would match for assignment (under sizeof, so we are safe from
side effects or any code actually getting generated), then explicitly cast
everywhere to the fixed-sized types.  Kills a bunch of bogus warnings about
constants being truncated (gcc, sparse), finds a pile of endianness problems
hidden by old noise (sparse).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Al Viro authored and Linus Torvalds committed Jul 17, 2007
1 parent cc040a8 commit d37c6e1
Showing 1 changed file with 9 additions and 7 deletions.
16 changes: 9 additions & 7 deletions include/asm-generic/unaligned.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
#define get_unaligned(ptr) \
__get_unaligned((ptr), sizeof(*(ptr)))
#define put_unaligned(x,ptr) \
__put_unaligned((__u64)(x), (ptr), sizeof(*(ptr)))
((void)sizeof(*(ptr)=(x)),\
__put_unaligned((__force __u64)(x), (ptr), sizeof(*(ptr))))

/*
* This function doesn't actually exist. The idea is that when
Expand Down Expand Up @@ -95,28 +96,29 @@ static inline void __ustw(__u16 val, __u16 *addr)
default: \
bad_unaligned_access_length(); \
}; \
(__typeof__(*(ptr)))val; \
(__force __typeof__(*(ptr)))val; \
})

#define __put_unaligned(val, ptr, size) \
do { \
({ \
void *__gu_p = ptr; \
switch (size) { \
case 1: \
*(__u8 *)__gu_p = val; \
*(__u8 *)__gu_p = (__force __u8)val; \
break; \
case 2: \
__ustw(val, __gu_p); \
__ustw((__force __u16)val, __gu_p); \
break; \
case 4: \
__ustl(val, __gu_p); \
__ustl((__force __u32)val, __gu_p); \
break; \
case 8: \
__ustq(val, __gu_p); \
break; \
default: \
bad_unaligned_access_length(); \
}; \
} while(0)
(void)0; \
})

#endif /* _ASM_GENERIC_UNALIGNED_H */

0 comments on commit d37c6e1

Please sign in to comment.