diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-03-29 22:00:11 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-03-30 17:35:50 +0100 |
commit | b3daa62b53109dba78c7937b3a6a0cd7d67865d5 (patch) | |
tree | 416cf979dfe87aa8c93ed7e26a71207f4eb2063d | |
parent | 1ed0955919913ad4f314e867fcbc76535acf010c (diff) | |
download | sparse-b3daa62b53109dba78c7937b3a6a0cd7d67865d5.tar.gz |
also accept casts of AS pointers to uintptr_t
Sparse will warn on casts removing the address space of a pointer
if the destination type is not unsigned long. But the type
'uintptr_t' should be more suited for this.
So, also accept casts of address-space qualified pointers to uintptr_t.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r-- | evaluate.c | 2 | ||||
-rw-r--r-- | validation/cast-from-as.c | 60 |
2 files changed, 61 insertions, 1 deletions
@@ -3022,7 +3022,7 @@ static struct symbol *evaluate_cast(struct expression *expr) tas = ttype->ctype.as; } - if (stype == &ulong_ctype && !Wcast_from_as) + if ((stype == &ulong_ctype || stype == uintptr_ctype) && !Wcast_from_as) sas = &bad_address_space; else if (sclass == TYPE_PTR) { examine_pointer_target(stype); diff --git a/validation/cast-from-as.c b/validation/cast-from-as.c new file mode 100644 index 00000000..8dda83ea --- /dev/null +++ b/validation/cast-from-as.c @@ -0,0 +1,60 @@ + +#define __kernel __attribute__((address_space(0))) +#define __user __attribute__((address_space(__user))) +#define __iomem __attribute__((address_space(__iomem))) +#define __percpu __attribute__((address_space(__percpu))) +#define __rcu __attribute__((address_space(__rcu))) + + +typedef struct s obj_t; + +static void expl(obj_t __kernel *k, obj_t __iomem *o, + obj_t __user *p, obj_t __percpu *pc, + obj_t __rcu *r) +{ + (__UINTPTR_TYPE__)(k); // OK + (unsigned long)(k); // OK + (void *)(k); // OK + (obj_t*)(k); // OK + (obj_t __kernel*)(k); // OK + + (__UINTPTR_TYPE__)(o); // OK + (unsigned long)(o); // OK + (void *)(o); + (obj_t*)(o); + (obj_t __iomem*)(o); // OK + + (__UINTPTR_TYPE__)(p); // OK + (unsigned long)(p); // OK + (void *)(p); + (obj_t*)(p); + (obj_t __user*)(p); // OK + + (__UINTPTR_TYPE__)(pc); // OK + (unsigned long)(pc); // OK + (void *)(pc); + (obj_t*)(pc); + (obj_t __percpu*)(pc); // OK + + (__UINTPTR_TYPE__)(r); // OK + (unsigned long)(r); // OK + (void *)(r); + (obj_t*)(r); + (obj_t __rcu*)(r); // OK +} + +/* + * check-name: cast-from-as + * check-command: sparse -Wno-cast-from-as $file + * + * 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 + * check-error-end + */ |