The patch b3daa62b5 ("also accept casts of AS pointers to uintptr_t") is bogus and allows uintptr_t as the *source type* instead of the *target type*. This was helped by a previous bug, in patch d96da358c ("stricter warning for explicit cast to ulong"), where a test for Wcast_from_as was wrongly added for the source type. Fix this by: * adding the test for uintptr_t to the target type; * removing the test for Wcast_from_as from the source type, replacing it by a test of Wcast_to_as; * clarify and extend the tge testcases. So, now, casts from uintptr_t to AS pointers are also allowed. Fixes: b3daa62b53109dba78c7937b3a6a0cd7d67865d5 Fixes: d96da358cfa0432f067a4e66940765883b80ee62 Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- evaluate.c | 4 +-- sparse.1 | 2 ++ validation/Waddress-space-all-attr.c | 14 +++++--- .../{cast-from-as.c => Waddress-space-from.c} | 21 ++++++----- validation/Waddress-space-strict.c | 1 - validation/Wcast-to-as.c | 36 +++++++++++++++++++ 6 files changed, 61 insertions(+), 17 deletions(-) rename validation/{cast-from-as.c => Waddress-space-from.c} (55%) create mode 100644 validation/Wcast-to-as.c diff --git a/evaluate.c b/evaluate.c index d9cd41d1f..3268333ab 100644 --- a/evaluate.c +++ b/evaluate.c @@ -3015,14 +3015,14 @@ static struct symbol *evaluate_cast(struct expression *expr) } } - if (ttype == &ulong_ctype && !Wcast_from_as) + if ((ttype == &ulong_ctype || ttype == uintptr_ctype) && !Wcast_from_as) tas = &bad_address_space; else if (tclass == TYPE_PTR) { examine_pointer_target(ttype); tas = ttype->ctype.as; } - if ((stype == &ulong_ctype || stype == uintptr_ctype) && !Wcast_from_as) + if ((stype == &ulong_ctype || stype == uintptr_ctype)) sas = &bad_address_space; else if (sclass == TYPE_PTR) { examine_pointer_target(stype); diff --git a/sparse.1 b/sparse.1 index 78d0b1ec4..beb484423 100644 --- a/sparse.1 +++ b/sparse.1 @@ -104,6 +104,8 @@ Sparse does not issues these warnings by default. Warn about casts which add an address space to a pointer type. A cast that includes \fB__attribute__((force))\fR will suppress this warning. +No warning is generated if the original type is \fBuintptr_t\fR +(or \fBunsigned long\fR). Sparse does not issue these warnings by default. . diff --git a/validation/Waddress-space-all-attr.c b/validation/Waddress-space-all-attr.c index 5b2d0f92f..b0c17693a 100644 --- a/validation/Waddress-space-all-attr.c +++ b/validation/Waddress-space-all-attr.c @@ -13,27 +13,27 @@ static void expl(obj_t __kernel *k, obj_t __iomem *o, obj_t __user *p, obj_t __percpu *pc, obj_t __rcu *r) { - (ulong)(k); + (ulong)(k); (__UINTPTR_TYPE__)(k); (void *)(k); (obj_t*)(k); (obj_t __kernel*)(k); - (ulong)(o); + (ulong)(o); (__UINTPTR_TYPE__)(o); (void *)(o); (obj_t*)(o); (obj_t __iomem*)(o); - (ulong)(p); + (ulong)(p); (__UINTPTR_TYPE__)(p); (void *)(p); (obj_t*)(p); (obj_t __user*)(p); - (ulong)(pc); + (ulong)(pc); (__UINTPTR_TYPE__)(pc); (void *)(pc); (obj_t*)(pc); (obj_t __percpu*)(pc); - (ulong)(r); + (ulong)(r); (__UINTPTR_TYPE__)(r); (void *)(r); (obj_t*)(r); (obj_t __rcu*)(r); @@ -45,15 +45,19 @@ static void expl(obj_t __kernel *k, obj_t __iomem *o, * * check-error-start Waddress-space-all-attr.c:21:10: warning: cast removes address space '<asn:2>' of expression +Waddress-space-all-attr.c:21:22: warning: cast removes address space '<asn:2>' of expression Waddress-space-all-attr.c:22:10: warning: cast removes address space '<asn:2>' of expression Waddress-space-all-attr.c:23:10: warning: cast removes address space '<asn:2>' of expression Waddress-space-all-attr.c:26:10: warning: cast removes address space '<asn:1>' of expression +Waddress-space-all-attr.c:26:22: warning: cast removes address space '<asn:1>' of expression Waddress-space-all-attr.c:27:10: warning: cast removes address space '<asn:1>' of expression Waddress-space-all-attr.c:28:10: warning: cast removes address space '<asn:1>' of expression Waddress-space-all-attr.c:31:10: warning: cast removes address space '<asn:3>' of expression +Waddress-space-all-attr.c:31:23: warning: cast removes address space '<asn:3>' of expression Waddress-space-all-attr.c:32:10: warning: cast removes address space '<asn:3>' of expression Waddress-space-all-attr.c:33:10: warning: cast removes address space '<asn:3>' of expression Waddress-space-all-attr.c:36:10: warning: cast removes address space '<asn:4>' of expression +Waddress-space-all-attr.c:36:22: warning: cast removes address space '<asn:4>' of expression Waddress-space-all-attr.c:37:10: warning: cast removes address space '<asn:4>' of expression Waddress-space-all-attr.c:38:10: warning: cast removes address space '<asn:4>' of expression * check-error-end diff --git a/validation/cast-from-as.c b/validation/Waddress-space-from.c similarity index 55% rename from validation/cast-from-as.c rename to validation/Waddress-space-from.c index 8dda83ea5..317a205b6 100644 --- a/validation/cast-from-as.c +++ b/validation/Waddress-space-from.c @@ -44,17 +44,20 @@ static void expl(obj_t __kernel *k, obj_t __iomem *o, } /* - * check-name: cast-from-as + * check-name: Waddress-space-from * check-command: sparse -Wno-cast-from-as $file + * check-description: Test the removal of AS from a pointer but only + * in the non-strict variant where casts to ulong (or uintptr_t) + * are allowed. * * check-error-start -cast-from-as.c:23:10: warning: cast removes address space '__iomem' of expression -cast-from-as.c:24:10: warning: cast removes address space '__iomem' of expression -cast-from-as.c:29:10: warning: cast removes address space '__user' of expression -cast-from-as.c:30:10: warning: cast removes address space '__user' of expression -cast-from-as.c:35:10: warning: cast removes address space '__percpu' of expression -cast-from-as.c:36:10: warning: cast removes address space '__percpu' of expression -cast-from-as.c:41:10: warning: cast removes address space '__rcu' of expression -cast-from-as.c:42:10: warning: cast removes address space '__rcu' of expression +Waddress-space-from.c:23:10: warning: cast removes address space '__iomem' of expression +Waddress-space-from.c:24:10: warning: cast removes address space '__iomem' of expression +Waddress-space-from.c:29:10: warning: cast removes address space '__user' of expression +Waddress-space-from.c:30:10: warning: cast removes address space '__user' of expression +Waddress-space-from.c:35:10: warning: cast removes address space '__percpu' of expression +Waddress-space-from.c:36:10: warning: cast removes address space '__percpu' of expression +Waddress-space-from.c:41:10: warning: cast removes address space '__rcu' of expression +Waddress-space-from.c:42:10: warning: cast removes address space '__rcu' of expression * check-error-end */ diff --git a/validation/Waddress-space-strict.c b/validation/Waddress-space-strict.c index 7987eb1db..a1c5b2771 100644 --- a/validation/Waddress-space-strict.c +++ b/validation/Waddress-space-strict.c @@ -27,7 +27,6 @@ static void expl(ulong u, void *v, obj_t *o, obj_t __user *p) * check-command: sparse -Wcast-from-as -Wcast-to-as $file * * check-error-start -Waddress-space-strict.c:9:10: warning: cast adds address space '<asn:1>' to expression Waddress-space-strict.c:12:10: warning: cast adds address space '<asn:1>' to expression Waddress-space-strict.c:17:10: warning: cast adds address space '<asn:1>' to expression Waddress-space-strict.c:19:10: warning: cast removes address space '<asn:1>' of expression diff --git a/validation/Wcast-to-as.c b/validation/Wcast-to-as.c new file mode 100644 index 000000000..8c5120910 --- /dev/null +++ b/validation/Wcast-to-as.c @@ -0,0 +1,36 @@ +#define __user __attribute__((address_space(1))) + +typedef __UINTPTR_TYPE__ uintptr_t; +typedef unsigned long ulong; +typedef struct s obj_t; + +static void expl(ulong u, uintptr_t uip, void *v, obj_t *o, obj_t __user *p) +{ + (obj_t*)(u); + (obj_t __user*)(u); + + (obj_t*)(uip); + (obj_t __user*)(uip); + + (obj_t*)(v); + (obj_t __user*)(v); + + (ulong)(o); + (void *)(o); + (obj_t*)(o); + (obj_t __user*)(o); + + (ulong)(p); + (obj_t __user*)(p); + +} + +/* + * check-name: cast-to-as + * check-command: sparse -Wcast-to-as $file + * + * check-error-start +Wcast-to-as.c:16:10: warning: cast adds address space '<asn:1>' to expression +Wcast-to-as.c:21:10: warning: cast adds address space '<asn:1>' to expression + * check-error-end + */ -- 2.21.0