aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-03-29 22:00:11 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-03-30 17:35:50 +0100
commitb3daa62b53109dba78c7937b3a6a0cd7d67865d5 (patch)
tree416cf979dfe87aa8c93ed7e26a71207f4eb2063d
parent1ed0955919913ad4f314e867fcbc76535acf010c (diff)
downloadsparse-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.c2
-rw-r--r--validation/cast-from-as.c60
2 files changed, 61 insertions, 1 deletions
diff --git a/evaluate.c b/evaluate.c
index 7c63d788..d9cd41d1 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -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
+ */