Linux-Sparse Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/4] fix evaluation of assignment and qualified arrays
@ 2020-07-10  0:13 Luc Van Oostenryck
  2020-07-10  0:13 ` [PATCH 1/4] add a testcase for assignment to const <type> (*)[] Luc Van Oostenryck
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2020-07-10  0:13 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

This series contains a tentative fix for a problem reported
today on the mailing list as well as some related testcases.
The problem concerns the assignment of pointers to const arrays,
like the following code:
	int a[2][3];
	const int (*p)[3] = a;
which was incorrectly given a warning.

Luc Van Oostenryck (4):
  add a testcase for assignment to const <type> (*)[]
  add another testcase  with const array/pointer
  add testcase for missing warning for assignment to const
  [RFC] fix evaluation error with assignment of qualified arrays

 evaluate.c                         |  4 +--
 validation/eval/array-quals-node.c | 29 ++++++++++++++++++
 validation/eval/array-quals0.c     |  6 ++++
 validation/eval/array-quals1.c     | 49 ++++++++++++++++++++++++++++++
 4 files changed, 86 insertions(+), 2 deletions(-)
 create mode 100644 validation/eval/array-quals-node.c
 create mode 100644 validation/eval/array-quals0.c
 create mode 100644 validation/eval/array-quals1.c

-- 
2.27.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/4] add a testcase for assignment to const <type> (*)[]
  2020-07-10  0:13 [PATCH 0/4] fix evaluation of assignment and qualified arrays Luc Van Oostenryck
@ 2020-07-10  0:13 ` Luc Van Oostenryck
  2020-07-10  0:13 ` [PATCH 2/4] add another testcase with const array/pointer Luc Van Oostenryck
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2020-07-10  0:13 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck, Ard Biesheuvel, Herbert Xu

You can assign a '<type>[]' to a 'const <type> *'. Likewise,
you can assign a '<type>[][N]' to a 'const <type> (*)[N]' but
sparse doesn't like this.

Analyzed-by: Ard Biesheuvel <ardb@kernel.org>
Reported-by: Herbert Xu <herbert@gondor.apana.org.au>
Link: https://lore.kernel.org/linux-crypto/20200709120937.GA13332@gondor.apana.org.au/
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 validation/eval/array-quals0.c | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 validation/eval/array-quals0.c

diff --git a/validation/eval/array-quals0.c b/validation/eval/array-quals0.c
new file mode 100644
index 000000000000..9cb08c1722d7
--- /dev/null
+++ b/validation/eval/array-quals0.c
@@ -0,0 +1,7 @@
+static int a[2][3];
+static const int (*p)[3] = a;
+
+/*
+ * check-name: array-quals0
+ * check-known-to-fail
+ */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/4] add another testcase  with const array/pointer
  2020-07-10  0:13 [PATCH 0/4] fix evaluation of assignment and qualified arrays Luc Van Oostenryck
  2020-07-10  0:13 ` [PATCH 1/4] add a testcase for assignment to const <type> (*)[] Luc Van Oostenryck
@ 2020-07-10  0:13 ` Luc Van Oostenryck
  2020-07-10  0:13 ` [PATCH 3/4] add testcase for missing warning for assignment to const Luc Van Oostenryck
  2020-07-10  0:13 ` [PATCH 4/4] [RFC] fix evaluation error with assignment of qualified arrays Luc Van Oostenryck
  3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2020-07-10  0:13 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

Those are cases that sparse should warn about but doesn't.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 validation/eval/array-quals1.c | 50 ++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)
 create mode 100644 validation/eval/array-quals1.c

diff --git a/validation/eval/array-quals1.c b/validation/eval/array-quals1.c
new file mode 100644
index 000000000000..a1c3905826d5
--- /dev/null
+++ b/validation/eval/array-quals1.c
@@ -0,0 +1,50 @@
+typedef const int ci_t;
+typedef       int  ia_t[2];
+typedef const int cia_t[2];
+
+static const int	ci__a[2];
+static ci_t		cit_a[2];
+static const ia_t	c_iat;
+static cia_t		ciat_;
+static cia_t		ciata[2];
+
+static const void *const ok_ci__a = &ci__a;
+static       void *const ko_ci__a = &ci__a;
+static const void *const ok_cit_a = &cit_a;
+static       void *const ko_cit_a = &cit_a;
+static const void *const ok_c_iat = &c_iat;
+static       void *const ko_c_iat = &c_iat;
+static const void *const ok_ciat_ = &ciat_;
+static       void *const ko_ciat_ = &ciat_;
+static const void *const ok_ciata = &ciata;
+static       void *const ko_ciata = &ciata;
+
+static volatile int	vi__a[2];
+static volatile void *const ok_vi__a = &vi__a;
+static          void *const ko_vi__a = &vi__a;
+
+/*
+ * check-name: array-quals1
+ * check-known-to-fail
+ *
+ * check-error-start
+eval/array-quals1.c:12:38: warning: incorrect type in initializer (different modifiers)
+eval/array-quals1.c:12:38:    expected void *static const [toplevel] ko_ci__a
+eval/array-quals1.c:12:38:    got int const ( * )[2]
+eval/array-quals1.c:14:38: warning: incorrect type in initializer (different modifiers)
+eval/array-quals1.c:14:38:    expected void *static const [toplevel] ko_cit_a
+eval/array-quals1.c:14:38:    got int const [usertype] ( * )[2]
+eval/array-quals1.c:16:38: warning: incorrect type in initializer (different modifiers)
+eval/array-quals1.c:16:38:    expected void *static const [toplevel] ko_c_iat
+eval/array-quals1.c:16:38:    got int const ( * )[2]
+eval/array-quals1.c:18:38: warning: incorrect type in initializer (different modifiers)
+eval/array-quals1.c:18:38:    expected void *static const [toplevel] ko_ciat_
+eval/array-quals1.c:18:38:    got int const ( * )[2]
+eval/array-quals1.c:20:38: warning: incorrect type in initializer (different modifiers)
+eval/array-quals1.c:20:38:    expected void *static const [toplevel] ko_ciata
+eval/array-quals1.c:20:38:    got int const [usertype] ( * )[2][2]
+eval/array-quals1.c:24:41: warning: incorrect type in initializer (different modifiers)
+eval/array-quals1.c:24:41:    expected void *static const [toplevel] ko_vi__a
+eval/array-quals1.c:24:41:    got int volatile ( * )[2]
+ * check-error-end
+ */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 3/4] add testcase for missing warning for assignment to const
  2020-07-10  0:13 [PATCH 0/4] fix evaluation of assignment and qualified arrays Luc Van Oostenryck
  2020-07-10  0:13 ` [PATCH 1/4] add a testcase for assignment to const <type> (*)[] Luc Van Oostenryck
  2020-07-10  0:13 ` [PATCH 2/4] add another testcase with const array/pointer Luc Van Oostenryck
@ 2020-07-10  0:13 ` Luc Van Oostenryck
  2020-07-10  0:13 ` [PATCH 4/4] [RFC] fix evaluation error with assignment of qualified arrays Luc Van Oostenryck
  3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2020-07-10  0:13 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

The problem is seems to be related with evaluate_dereference()
where all mods are dropped when the type is a node.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 validation/eval/array-quals-node.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 validation/eval/array-quals-node.c

diff --git a/validation/eval/array-quals-node.c b/validation/eval/array-quals-node.c
new file mode 100644
index 000000000000..99a4db13e4da
--- /dev/null
+++ b/validation/eval/array-quals-node.c
@@ -0,0 +1,29 @@
+struct s {
+	int a;
+	int b[3];
+	int c[2][3];
+};
+
+struct c {
+	const struct s s;
+};
+
+extern struct c v;
+
+void f(void)
+{
+	  v.s.a = 0;
+	 *v.s.b = 0;
+	**v.s.c = 0;
+}
+
+/*
+ * check-name: array-quals-node
+ * check-known-to-fail
+ *
+ * check-error-start
+eval/array-quals-node.c:15:14: error: assignment to const expression
+eval/array-quals-node.c:16:14: error: assignment to const expression
+eval/array-quals-node.c:17:14: error: assignment to const expression
+ * check-error-end
+ */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 4/4] [RFC] fix evaluation error with assignment of qualified arrays
  2020-07-10  0:13 [PATCH 0/4] fix evaluation of assignment and qualified arrays Luc Van Oostenryck
                   ` (2 preceding siblings ...)
  2020-07-10  0:13 ` [PATCH 3/4] add testcase for missing warning for assignment to const Luc Van Oostenryck
@ 2020-07-10  0:13 ` Luc Van Oostenryck
  3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2020-07-10  0:13 UTC (permalink / raw)
  To: linux-sparse; +Cc: Luc Van Oostenryck

This is a fix for a problem reported today to the mailing list.

In check_assignment_types(), the first 'level' is checked by the
function itself but the next level is checked by the type_difference().
This later function take as arguments, beside the types to be
checked, the modifiers that can be assumed for each of the types
(this works as a kind of reverse mask).
But these modifiers are taken from target_qualifiers() which,
purposely ignore the modifiers for arrays introduced in commit
    984b7b66457c ("[PATCH] deal correctly with qualifiers on arrays")
with the comment:
    "Pointers to any array are considered as pointers to unqualified
    type as far as implicit conversions are concerned"

But by dropping these modifiers, type_difference() reports
incorrect results for pointers to qualified arrays.

So, do not use target_qualifiers() but take the modifiers directly
from the ctypes. Admittingly, I'm far from sure that this is the
right fix but it solve several wrong cases.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 evaluate.c                     | 4 ++--
 validation/eval/array-quals0.c | 1 -
 validation/eval/array-quals1.c | 1 -
 3 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/evaluate.c b/evaluate.c
index f515ce6f2de6..dddea76182ad 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1444,8 +1444,8 @@ static int check_assignment_types(struct symbol *target, struct expression **rp,
 		}
 		b1 = examine_pointer_target(t);
 		b2 = examine_pointer_target(s);
-		mod1 = target_qualifiers(t);
-		mod2 = target_qualifiers(s);
+		mod1 = t->ctype.modifiers & MOD_IGN;
+		mod2 = s->ctype.modifiers & MOD_IGN;
 		if (whitelist_pointers(b1, b2)) {
 			/*
 			 * assignments to/from void * are OK, provided that
diff --git a/validation/eval/array-quals0.c b/validation/eval/array-quals0.c
index 9cb08c1722d7..30727490289e 100644
--- a/validation/eval/array-quals0.c
+++ b/validation/eval/array-quals0.c
@@ -3,5 +3,4 @@ static const int (*p)[3] = a;
 
 /*
  * check-name: array-quals0
- * check-known-to-fail
  */
diff --git a/validation/eval/array-quals1.c b/validation/eval/array-quals1.c
index a1c3905826d5..d3e54f3ec8dc 100644
--- a/validation/eval/array-quals1.c
+++ b/validation/eval/array-quals1.c
@@ -25,7 +25,6 @@ static          void *const ko_vi__a = &vi__a;
 
 /*
  * check-name: array-quals1
- * check-known-to-fail
  *
  * check-error-start
 eval/array-quals1.c:12:38: warning: incorrect type in initializer (different modifiers)
-- 
2.27.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, back to index

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-10  0:13 [PATCH 0/4] fix evaluation of assignment and qualified arrays Luc Van Oostenryck
2020-07-10  0:13 ` [PATCH 1/4] add a testcase for assignment to const <type> (*)[] Luc Van Oostenryck
2020-07-10  0:13 ` [PATCH 2/4] add another testcase with const array/pointer Luc Van Oostenryck
2020-07-10  0:13 ` [PATCH 3/4] add testcase for missing warning for assignment to const Luc Van Oostenryck
2020-07-10  0:13 ` [PATCH 4/4] [RFC] fix evaluation error with assignment of qualified arrays Luc Van Oostenryck

Linux-Sparse Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-sparse/0 linux-sparse/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-sparse linux-sparse/ https://lore.kernel.org/linux-sparse \
		linux-sparse@vger.kernel.org
	public-inbox-index linux-sparse

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-sparse


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git