summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-12-19 21:03:55 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-12-19 21:03:55 +0100
commit41c40878c422428749f29a5fa2c7b198a8ef9921 (patch)
tree9e957d1fa5e3a7931bc6e003f8868bb01a77c944
parent1cf02bb504bdb0e3a54e52e173cf48d1928a00ce (diff)
parent6002ded74587a1469fcd930dd46dc89eb3307982 (diff)
downloadsparse-41c40878c422428749f29a5fa2c7b198a8ef9921.tar.gz
Merge branch 'bitwise-ptr'
* warn on casts to/from bitwise pointers
-rw-r--r--evaluate.c19
-rw-r--r--lib.c2
-rw-r--r--lib.h1
-rw-r--r--sparse.16
-rw-r--r--validation/bitwise-cast-ptr.c33
-rw-r--r--validation/bitwise-cast.c6
6 files changed, 67 insertions, 0 deletions
diff --git a/evaluate.c b/evaluate.c
index 64c02564..4c8c002e 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -3045,6 +3045,25 @@ static struct symbol *evaluate_cast(struct expression *expr)
if (ttype == &bool_ctype)
cast_to_bool(expr);
+ // checks pointers to restricted
+ while (Wbitwise_pointer && tclass == TYPE_PTR && sclass == TYPE_PTR) {
+ tclass = classify_type(ttype->ctype.base_type, &ttype);
+ sclass = classify_type(stype->ctype.base_type, &stype);
+ if (ttype == stype)
+ break;
+ if (!ttype || !stype)
+ break;
+ if (ttype == &void_ctype || stype == &void_ctype)
+ break;
+ if (tclass & TYPE_RESTRICT) {
+ warning(expr->pos, "cast to %s", show_typename(ctype));
+ break;
+ }
+ if (sclass & TYPE_RESTRICT) {
+ warning(expr->pos, "cast from %s", show_typename(source->ctype));
+ break;
+ }
+ }
out:
return ctype;
}
diff --git a/lib.c b/lib.c
index 9f8213df..7bf66cd0 100644
--- a/lib.c
+++ b/lib.c
@@ -253,6 +253,7 @@ static struct token *pre_buffer_end = NULL;
int Waddress = 0;
int Waddress_space = 1;
int Wbitwise = 1;
+int Wbitwise_pointer = 0;
int Wcast_from_as = 0;
int Wcast_to_as = 0;
int Wcast_truncate = 1;
@@ -684,6 +685,7 @@ static const struct flag warnings[] = {
{ "address", &Waddress },
{ "address-space", &Waddress_space },
{ "bitwise", &Wbitwise },
+ { "bitwise-pointer", &Wbitwise_pointer},
{ "cast-from-as", &Wcast_from_as },
{ "cast-to-as", &Wcast_to_as },
{ "cast-truncate", &Wcast_truncate },
diff --git a/lib.h b/lib.h
index f2f5f839..322408be 100644
--- a/lib.h
+++ b/lib.h
@@ -139,6 +139,7 @@ extern int preprocess_only;
extern int Waddress;
extern int Waddress_space;
extern int Wbitwise;
+extern int Wbitwise_pointer;
extern int Wcast_from_as;
extern int Wcast_to_as;
extern int Wcast_truncate;
diff --git a/sparse.1 b/sparse.1
index ccee2808..096c5b08 100644
--- a/sparse.1
+++ b/sparse.1
@@ -77,6 +77,12 @@ Sparse issues these warnings by default. To turn them off, use
\fB\-Wno\-bitwise\fR.
.
.TP
+.B \-Wbitwise\-pointer
+Same as \fB\-Wbitwise\fR but for casts to or from pointers to bitwise types.
+
+Sparse does not issue these warnings by default.
+.
+.TP
.B \-Wcast\-from\-as
Warn about which remove an address space to a pointer type.
diff --git a/validation/bitwise-cast-ptr.c b/validation/bitwise-cast-ptr.c
new file mode 100644
index 00000000..3f2bfdaf
--- /dev/null
+++ b/validation/bitwise-cast-ptr.c
@@ -0,0 +1,33 @@
+#define __bitwise __attribute__((bitwise))
+#define __force __attribute__((force))
+
+typedef unsigned int u32;
+typedef unsigned int __bitwise __be32;
+
+static __be32* tobi(u32 *x)
+{
+ return x; // should warn, implicit cast
+}
+
+static __be32* tobe(u32 *x)
+{
+ return (__be32 *) x; // should warn, explicit cast
+}
+
+static __be32* tobf(u32 *x)
+{
+ return (__force __be32 *) x; // should not warn, forced cast
+ return (__be32 __force *) x; // should not warn, forced cast
+}
+
+/*
+ * check-name: cast of bitwise pointers
+ * check-command: sparse -Wbitwise -Wbitwise-pointer $file
+ *
+ * check-error-start
+bitwise-cast-ptr.c:9:16: warning: incorrect type in return expression (different base types)
+bitwise-cast-ptr.c:9:16: expected restricted __be32 [usertype] *
+bitwise-cast-ptr.c:9:16: got unsigned int [usertype] *x
+bitwise-cast-ptr.c:14:17: warning: cast to restricted __be32 [usertype] *<noident>
+ * check-error-end
+ */
diff --git a/validation/bitwise-cast.c b/validation/bitwise-cast.c
index baeca29e..0583461c 100644
--- a/validation/bitwise-cast.c
+++ b/validation/bitwise-cast.c
@@ -29,6 +29,12 @@ static __be32 quux(void)
return (__be32)1729;
}
+/* Explicit case of nonzero forced, legal */
+static __be32 quuy(void)
+{
+ return (__attribute__((force)) __be32) 1730;
+}
+
/*
* check-name: conversions to bitwise types
* check-command: sparse -Wbitwise $file