Fix _IOC_TYPECHECK sparse error
Subsystems (2)
PATCH 1/1 Fix _IOC_TYPECHECK sparse error
Andrew, can you merge this for 3.15 or 3.16 (you decide)? While it fixes a sparse error for the media subsystem, it is not really appropriate to go through our media tree.
Thanks,
Hans
When running sparse over drivers/media/v4l2-core/v4l2-ioctl.c I get these errors:
drivers/media/v4l2-core/v4l2-ioctl.c:2043:9: error: bad integer constant expression drivers/media/v4l2-core/v4l2-ioctl.c:2044:9: error: bad integer constant expression drivers/media/v4l2-core/v4l2-ioctl.c:2045:9: error: bad integer constant expression drivers/media/v4l2-core/v4l2-ioctl.c:2046:9: error: bad integer constant expression
etc.
The root cause of that turns out to be in include/asm-generic/ioctl.h:
#include <uapi/asm-generic/ioctl.h>
/* provoke compile error for invalid uses of size argument */ extern unsigned int __invalid_size_argument_for_IOC;
#define _IOC_TYPECHECK(t) \
((sizeof(t) == sizeof(t[1]) && \
sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
sizeof(t) : __invalid_size_argument_for_IOC)If it is defined as this (as is already done if __KERNEL__ is not defined):
#define _IOC_TYPECHECK(t) (sizeof(t))
then all is well with the world.
This patch allows sparse to work correctly.
--- include/asm-generic/ioctl.h | 5 +++++ 1 file changed, 5 insertions(+)
include/asm-generic/ioctl.h +5 -0
@@ -3,10 +3,15 @@#include <uapi/asm-generic/ioctl.h> +#ifdef __CHECKER__ +#define _IOC_TYPECHECK (t) (sizeof(t)) +#else /* provoke compile error for invalid uses of size argument */ extern unsigned int __invalid_size_argument_for_IOC;#define _IOC_TYPECHECK (t) \ ((sizeof(t) == sizeof(t[1]) && \ sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ sizeof(t) : __invalid_size_argument_for_IOC) +#endif +#endif /* _ASM_GENERIC_IOCTL_H */
Signature · 1 line
2.0.0.rc0
Quoted 45 lines · On Fri, 09 May 2014 09:43:58 +0200 Hans Verkuil <[email protected]> wrote:
Andrew, can you merge this for 3.15 or 3.16 (you decide)? While it fixes a sparse error for the media subsystem, it is not really appropriate to go through our media tree.
Thanks,
Hans
When running sparse over
drivers/media/v4l2-core/v4l2-ioctl.cI get these errors:
drivers/media/v4l2-core/v4l2-ioctl.c:2043:9: error: bad integer constant expressiondrivers/media/v4l2-core/v4l2-ioctl.c:2044:9: error: bad integer constant expressiondrivers/media/v4l2-core/v4l2-ioctl.c:2045:9: error: bad integer constant expressiondrivers/media/v4l2-core/v4l2-ioctl.c:2046:9: error: bad integer constant expressionetc.
The root cause of that turns out to be in
include/asm-generic/ioctl.h:#include <
uapi/asm-generic/ioctl.h>/* provoke compile error for invalid uses of size argument */ extern unsigned int
__invalid_size_argument_for_IOC;#define _IOC_TYPECHECK(t) \ ((sizeof(t) == sizeof(t[1]) && \ sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ sizeof(t) : __invalid_size_argument_for_IOC)If it is defined as this (as is already done if
__KERNEL__is not defined):#define
_IOC_TYPECHECK(t)(sizeof(t))then all is well with the world.
This patch allows sparse to work correctly.
include/asm-generic/ioctl.h +2
-0@@ -3,10 +3,15 @@#include <uapi/asm-generic/ioctl.h> +#ifdef __CHECKER__ +#define _IOC_TYPECHECK (t) (sizeof(t))
include/asm-generic/ioctl.h line 17
Quoted 10 lines
include/asm-generic/ioctl.h +3
-0+#else /* provoke compile error for invalid uses of size argument */ extern unsigned int __invalid_size_argument_for_IOC;#define _IOC_TYPECHECK (t) \ ((sizeof(t) == sizeof(t[1]) && \ sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ sizeof(t) : __invalid_size_argument_for_IOC) +#endif +#endif /* _ASM_GENERIC_IOCTL_H */
Can't we use BUILD_BUG_ON() here? That's neater, more standard and BUILD_BUG_ON() already has sparse handling.
Quoted 45 lines · Andrew Morton
Quoted 43 lines · On Fri, 09 May 2014 09:43:58 +0200 Hans Verkuil <[email protected]> wrote:
Andrew, can you merge this for 3.15 or 3.16 (you decide)? While it fixes a sparse error for the media subsystem, it is not really appropriate to go through our media tree.
Thanks,
Hans
When running sparse over
drivers/media/v4l2-core/v4l2-ioctl.cI get these errors:
drivers/media/v4l2-core/v4l2-ioctl.c:2043:9: error: bad integer constant expressiondrivers/media/v4l2-core/v4l2-ioctl.c:2044:9: error: bad integer constant expressiondrivers/media/v4l2-core/v4l2-ioctl.c:2045:9: error: bad integer constant expressiondrivers/media/v4l2-core/v4l2-ioctl.c:2046:9: error: bad integer constant expressionetc.
The root cause of that turns out to be in
include/asm-generic/ioctl.h:#include <
uapi/asm-generic/ioctl.h>/* provoke compile error for invalid uses of size argument */ extern unsigned int
__invalid_size_argument_for_IOC;#define _IOC_TYPECHECK(t) \ ((sizeof(t) == sizeof(t[1]) && \ sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ sizeof(t) : __invalid_size_argument_for_IOC)If it is defined as this (as is already done if
__KERNEL__is not defined):#define
_IOC_TYPECHECK(t)(sizeof(t))then all is well with the world.
This patch allows sparse to work correctly.
include/asm-generic/ioctl.h +0
-0@@ -3,10 +3,15 @@#include <uapi/asm-generic/ioctl.h>
Quoted 15 lines
include/asm-generic/ioctl.h line 17
Quoted 12 lines
include/asm-generic/ioctl.h +5
-0+#ifdef __CHECKER__ +#define _IOC_TYPECHECK (t) (sizeof(t)) +#else /* provoke compile error for invalid uses of size argument */ extern unsigned int __invalid_size_argument_for_IOC;#define _IOC_TYPECHECK (t) \ ((sizeof(t) == sizeof(t[1]) && \ sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ sizeof(t) : __invalid_size_argument_for_IOC) +#endif +#endif /* _ASM_GENERIC_IOCTL_H */ Can't we use
BUILD_BUG_ON()here? That's neater, more standard andBUILD_BUG_ON()already has sparse handling.
I don't think so. BUILD_BUG_ON is not meant to be used in an expression, whereas _IOC_TYPECHECK(t) is (it should return sizeof(t)).
This looked promising at first sight:
#define _IOC_TYPECHECK(t) \
({BUILD_BUG_ON(sizeof(t) == sizeof(t[1]) && sizeof(t) < (1 << _IOC_SIZEBITS)); \
sizeof(t);})But it leads to 'case label does not reduce to an integer constant' compile errors.
And a typical ioctl define expands to this horror:
case (((2U) << (((0 +8)+8)+14)) | ((('M')) << (0 +8)) | (((1)) << 0) | (((({do { bool __cond = !(!(sizeof(int) == sizeof(int[1]) && sizeof(int) < (1 << 14))); extern void __compiletime_assert_1909(void) __attribute__((error("BUILD_BUG_ON failed: " "sizeof(int) == sizeof(int[1]) && sizeof(int) < (1 << _IOC_SIZEBITS)"))); if (__cond) __compiletime_assert_1909(); do { } while (0); } while (0); sizeof(int);}))) << ((0 +8)+8))):
which also explains the errors: case labels with function calls in them won't compile.
So I think my proposed patch is the best approach.
Regards,
Hans