fix allowing casts of AS pointers to uintptr_t
diff mbox series

Message ID 20190331234810.46675-1-luc.vanoostenryck@gmail.com
State Mainlined, archived
Headers show
Series
  • fix allowing casts of AS pointers to uintptr_t
Related show

Commit Message

Luc Van Oostenryck March 31, 2019, 11:48 p.m. UTC
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>
---
 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

Patch
diff mbox series

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
+ */