diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-03-31 22:23:23 +0200 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-04-01 01:46:44 +0200 |
commit | 3f359ea14423d05b5096d414fbc01ca4cc3839df (patch) | |
tree | 033d96d84a71649a38221b3ecfbe3b3193b202b2 | |
parent | c4c9935b129f63fe837bab2e1e3e5db6d32b7fb8 (diff) | |
download | sparse-3f359ea14423d05b5096d414fbc01ca4cc3839df.tar.gz |
fix allowing casts of AS pointers to uintptr_t
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@gmail.com>
-rw-r--r-- | evaluate.c | 4 | ||||
-rw-r--r-- | sparse.1 | 2 | ||||
-rw-r--r-- | validation/Waddress-space-all-attr.c | 14 | ||||
-rw-r--r-- | validation/Waddress-space-from.c (renamed from validation/cast-from-as.c) | 21 | ||||
-rw-r--r-- | validation/Waddress-space-strict.c | 1 | ||||
-rw-r--r-- | validation/Wcast-to-as.c | 36 |
6 files changed, 61 insertions, 17 deletions
@@ -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); @@ -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 5b2d0f92..b0c17693 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 index 8dda83ea..317a205b 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 7987eb1d..a1c5b277 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 00000000..8c512091 --- /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 + */ |