All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 07/13] evaluate: check static storage duration objects' intializers' constness
@ 2015-07-22 23:19 Nicolai Stange
  2016-01-09 18:04 ` Luc Van Oostenryck
  0 siblings, 1 reply; 8+ messages in thread
From: Nicolai Stange @ 2015-07-22 23:19 UTC (permalink / raw)
  To: linux-sparse

Initializers of static storage duration objects shall be constant
expressions [6.7.8(4)].

Warn if that requirement is not met.

Identify static storage duration objects by having either of
MOD_TOPLEVEL or MOD_STATIC set.

Check an initializer's constness at the lowest possible subobject
level, i.e. at the level of the "assignment-expression" production
in [6.7.8].

For compound objects, make handle_list_initializer() pass the
surrounding object's storage duration modifiers down to
handle_simple_initializer() at subobject initializer evaluation.

Signed-off-by: Nicolai Stange <nicstange@gmail.com>
---
 evaluate.c                  |  25 +++++++++-
 validation/constexpr-init.c | 109 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 validation/constexpr-init.c

diff --git a/evaluate.c b/evaluate.c
index c38b893..a65cc0c 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -2466,6 +2466,7 @@ static void handle_list_initializer(struct expression *expr,
 {
 	struct expression *e, *last = NULL, *top = NULL, *next;
 	int jumped = 0;
+	unsigned long old_modifiers;
 
 	FOR_EACH_PTR(expr->expr_list, e) {
 		struct expression **v;
@@ -2520,8 +2521,21 @@ found:
 		else
 			v = &top->ident_expression;
 
-		if (handle_simple_initializer(v, 1, lclass, top->ctype))
+		/*
+		 * Temporarily copy storage modifiers down from
+		 * surrounding type such that
+		 * handle_simple_initializer() can check
+		 * initializations of subobjects with static storage
+		 * duration.
+		 */
+		old_modifiers = top->ctype->ctype.modifiers;
+		top->ctype->ctype.modifiers =
+			old_modifiers | (ctype->ctype.modifiers & MOD_STORAGE);
+		if (handle_simple_initializer(v, 1, lclass, top->ctype)) {
+			top->ctype->ctype.modifiers = old_modifiers;
 			continue;
+		}
+		top->ctype->ctype.modifiers = old_modifiers;
 
 		if (!(lclass & TYPE_COMPOUND)) {
 			warning(e->pos, "bogus scalar initializer");
@@ -2631,6 +2645,15 @@ static int handle_simple_initializer(struct expression **ep, int nested,
 		if (!evaluate_expression(e))
 			return 1;
 		compatible_assignment_types(e, ctype, ep, "initializer");
+		/*
+		 * Initializers for static storage duration objects
+		 * shall be constant expressions or a string literal [6.7.8(4)].
+		 */
+		if ((ctype->ctype.modifiers & (MOD_TOPLEVEL | MOD_STATIC)) &&
+			!(e->flags & (EXPR_FLAG_ARITH_CONST_EXPR
+					| EXPR_FLAG_ADDR_CONST_EXPR)))
+			warning(e->pos, "initializer for static storage duration object is not a constant expression");
+
 		return 1;
 	}
 
diff --git a/validation/constexpr-init.c b/validation/constexpr-init.c
new file mode 100644
index 0000000..6c412b8
--- /dev/null
+++ b/validation/constexpr-init.c
@@ -0,0 +1,109 @@
+static int a = 1;					// OK
+static int b[2] = {1, 1};				// OK
+static void c(void) {}
+
+static int *d = &a;					// OK
+static int *e = &b[1];					// OK
+static int *f = b;					// OK
+static void (*g)(void) = c;				// OK
+static void (*h)(void) = &c;				// OK
+static int *i = (int*)0;				// OK
+static int *j = d;					// KO
+static int *k = (int*)0 + 1;				// OK
+
+static int *l = &a + 1;				// OK
+static int *m = &b[1] + 1;				// OK
+static int *n = b + 1;					// OK
+static int *o = d + 1;					// KO
+
+static int *p = &*&a;					// OK
+static int *q = &*&b[1];				// OK
+static int *r = &*b;					// OK
+static int *s = &*d;					// KO
+
+static int *t = &*(&a + 1);				// OK
+static int *u = &*(&b[1] + 1);				// OK
+static int *v = &*(b + 1);				// OK
+static int *w = &*(d + 1);				// KO
+
+
+struct A {
+	int a;
+	int b[2];
+};
+
+struct B {
+	int c;
+	struct A d;
+};
+
+static struct B x= {1, {1, {1, 1}}};				// OK
+static struct B y= {a, {1, {1, 1}}};				// KO
+static struct B z= {1, {a, {1, 1}}};				// KO
+static struct B aa= {1, {1, {a, 1}}};				// KO
+static struct B ab= {1, {1, {1, a}}};				// KO
+static struct B ac= {.c = 1, .d = {.a = 1, .b = {1, 1}}};	// OK
+static struct B ad= {.c = a, .d = {.a = 1, .b = {1, 1}}};	// KO
+static struct B ae= {.c = 1, .d = {.a = a, .b = {1, 1}}};	// KO
+static struct B af= {.c = 1, .d = {.a = 1, .b = {a, 1}}};	// KO
+static struct B ag= {.c = 1, .d = {.a = 1, .b = {1, a}}};	// KO
+
+static int *ah = &x.d.a;		// OK
+static int *ai = &(&x.d)->a;		// OK
+static int *aj = x.d.b;		// OK
+static int *ak = (&x.d)->b;		// OK
+static int *al = &x.d.b[1];		// OK
+static int *am = &(&x.d)->b[1];	// OK
+
+static int an[] = {a, 1};				// KO
+static int ao[] = {1, a};				// KO
+static int ap[] = {[0] = a, [1] = 1};			// KO
+static int aq[] = {[0] = 1, [1] = a};			// KO
+
+static char *ar = "foobar";				// OK
+
+static void as(void) {
+	int a = 0;
+	int b = a;		// OK
+}
+
+static void at(void) {
+	int a = 1;
+	static int b = a;	// KO
+}
+
+static void au(void) {
+	int a = 1;
+	static int *b = &a;	// KO
+}
+
+static void av(void) {
+	static int a = 1;
+	static int *b = &a;	// OK
+}
+
+
+/*
+ * check-name: Static storage object initializer constness verification.
+ *
+ * check-error-start
+constexpr-init.c:11:17: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:17:19: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:22:19: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:27:22: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:41:21: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:42:25: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:43:30: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:44:33: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:46:27: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:47:41: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:48:50: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:49:53: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:58:20: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:59:23: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:60:26: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:61:35: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:72:24: warning: initializer for static storage duration object is not a constant expression
+constexpr-init.c:77:26: warning: initializer for static storage duration object is not a constant expression
+ * check-error-end
+ */
-- 
2.4.5


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

* Re: [PATCH RFC 07/13] evaluate: check static storage duration objects' intializers' constness
  2015-07-22 23:19 [PATCH RFC 07/13] evaluate: check static storage duration objects' intializers' constness Nicolai Stange
@ 2016-01-09 18:04 ` Luc Van Oostenryck
  2016-01-09 22:28   ` Nicolai Stange
  0 siblings, 1 reply; 8+ messages in thread
From: Luc Van Oostenryck @ 2016-01-09 18:04 UTC (permalink / raw)
  To: Nicolai Stange; +Cc: linux-sparse

On Thu, Jul 23, 2015 at 01:19:09AM +0200, Nicolai Stange wrote:
> Initializers of static storage duration objects shall be constant
> expressions [6.7.8(4)].
> 
> Warn if that requirement is not met.
> 
> Identify static storage duration objects by having either of
> MOD_TOPLEVEL or MOD_STATIC set.
> 
> Check an initializer's constness at the lowest possible subobject
> level, i.e. at the level of the "assignment-expression" production
> in [6.7.8].
> 
> For compound objects, make handle_list_initializer() pass the
> surrounding object's storage duration modifiers down to
> handle_simple_initializer() at subobject initializer evaluation.


This patch makes validation/{builtin_bswap,choose_expr}.c fail.
Of course, it's directly related to the purpose of the patch but
then the test should be adapted.


Yours,
Luc

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

* Re: [PATCH RFC 07/13] evaluate: check static storage duration objects' intializers' constness
  2016-01-09 18:04 ` Luc Van Oostenryck
@ 2016-01-09 22:28   ` Nicolai Stange
  2016-01-11 18:02     ` Luc Van Oostenryck
  0 siblings, 1 reply; 8+ messages in thread
From: Nicolai Stange @ 2016-01-09 22:28 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: Nicolai Stange, linux-sparse

Luc Van Oostenryck <luc.vanoostenryck@gmail.com> writes:

> On Thu, Jul 23, 2015 at 01:19:09AM +0200, Nicolai Stange wrote:
>> Initializers of static storage duration objects shall be constant
>> expressions [6.7.8(4)].
>> 
>> Warn if that requirement is not met.
>> 
>> Identify static storage duration objects by having either of
>> MOD_TOPLEVEL or MOD_STATIC set.
>> 
>> Check an initializer's constness at the lowest possible subobject
>> level, i.e. at the level of the "assignment-expression" production
>> in [6.7.8].
>> 
>> For compound objects, make handle_list_initializer() pass the
>> surrounding object's storage duration modifiers down to
>> handle_simple_initializer() at subobject initializer evaluation.
>
>
> This patch makes validation/{builtin_bswap,choose_expr}.c fail.
> Of course, it's directly related to the purpose of the patch but
> then the test should be adapted.
>

Yes, you are absolutely right. However, as mentioned in this RFC series'
cover letter, I decided to leave these two failers as is "for the
moment". Certainly this is anything but best practice and I can only
apologize for sending you half (well 97%) baken patches -- and promise
to never do it again...

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

* Re: [PATCH RFC 07/13] evaluate: check static storage duration objects' intializers' constness
  2016-01-09 22:28   ` Nicolai Stange
@ 2016-01-11 18:02     ` Luc Van Oostenryck
  2016-01-11 18:15       ` Nicolai Stange
  0 siblings, 1 reply; 8+ messages in thread
From: Luc Van Oostenryck @ 2016-01-11 18:02 UTC (permalink / raw)
  To: Nicolai Stange; +Cc: linux-sparse

On Sat, Jan 09, 2016 at 11:28:08PM +0100, Nicolai Stange wrote:
> Luc Van Oostenryck <luc.vanoostenryck@gmail.com> writes:
> 
> > On Thu, Jul 23, 2015 at 01:19:09AM +0200, Nicolai Stange wrote:
> >> Initializers of static storage duration objects shall be constant
> >> expressions [6.7.8(4)].
> >> 
> >> Warn if that requirement is not met.
> >> 
> >> Identify static storage duration objects by having either of
> >> MOD_TOPLEVEL or MOD_STATIC set.
> >> 
> >> Check an initializer's constness at the lowest possible subobject
> >> level, i.e. at the level of the "assignment-expression" production
> >> in [6.7.8].
> >> 
> >> For compound objects, make handle_list_initializer() pass the
> >> surrounding object's storage duration modifiers down to
> >> handle_simple_initializer() at subobject initializer evaluation.
> >
> >
> > This patch makes validation/{builtin_bswap,choose_expr}.c fail.
> > Of course, it's directly related to the purpose of the patch but
> > then the test should be adapted.
> >
> 
> Yes, you are absolutely right. However, as mentioned in this RFC series'
> cover letter, I decided to leave these two failers as is "for the moment".

It's fine then.
I just wanted to be sure that you was aware of it.

> Certainly this is anything but best practice and I can only
> apologize for sending you half (well 97%) baken patches -- and promise
> to never do it again...

Personally, I think that drafts are very fine.
They're the basis on which we, developers, can exchange ideas.
And your patches are far from drafts, they are already finely coocked.

But just to be sure to avoid any misunderstanding:
you know that I'm not the maintainer, just a reviewer. Right?


Yours,
Luc

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

* Re: [PATCH RFC 07/13] evaluate: check static storage duration objects' intializers' constness
  2016-01-11 18:02     ` Luc Van Oostenryck
@ 2016-01-11 18:15       ` Nicolai Stange
  2016-01-11 19:28         ` Josh Triplett
  0 siblings, 1 reply; 8+ messages in thread
From: Nicolai Stange @ 2016-01-11 18:15 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: Nicolai Stange, linux-sparse

Luc Van Oostenryck <luc.vanoostenryck@gmail.com> writes:

> On Sat, Jan 09, 2016 at 11:28:08PM +0100, Nicolai Stange wrote:
>> Luc Van Oostenryck <luc.vanoostenryck@gmail.com> writes:
>> 
>> > On Thu, Jul 23, 2015 at 01:19:09AM +0200, Nicolai Stange wrote:
>> >> Initializers of static storage duration objects shall be constant
>> >> expressions [6.7.8(4)].
>> >> 
>> >> Warn if that requirement is not met.
>> >> 
>> >> Identify static storage duration objects by having either of
>> >> MOD_TOPLEVEL or MOD_STATIC set.
>> >> 
>> >> Check an initializer's constness at the lowest possible subobject
>> >> level, i.e. at the level of the "assignment-expression" production
>> >> in [6.7.8].
>> >> 
>> >> For compound objects, make handle_list_initializer() pass the
>> >> surrounding object's storage duration modifiers down to
>> >> handle_simple_initializer() at subobject initializer evaluation.
>> >
>> >
>> > This patch makes validation/{builtin_bswap,choose_expr}.c fail.
>> > Of course, it's directly related to the purpose of the patch but
>> > then the test should be adapted.
>> >
>> 
>> Yes, you are absolutely right. However, as mentioned in this RFC series'
>> cover letter, I decided to leave these two failers as is "for the moment".
>
> It's fine then.
> I just wanted to be sure that you was aware of it.
>
>> Certainly this is anything but best practice and I can only
>> apologize for sending you half (well 97%) baken patches -- and promise
>> to never do it again...
>
> Personally, I think that drafts are very fine.
> They're the basis on which we, developers, can exchange ideas.
> And your patches are far from drafts, they are already finely coocked.
>
> But just to be sure to avoid any misunderstanding:
> you know that I'm not the maintainer, just a reviewer. Right?

Yes, I know that:
  https://sparse.wiki.kernel.org/index.php/Main_Page

Btw, this remembers me of the fact that Josh Triplett is still listed as
a maintainer in sparse.1

Either of {web,man}page is wrong about that. Or both are incomplete and
we have actually got two maintainers here?

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

* Re: [PATCH RFC 07/13] evaluate: check static storage duration objects' intializers' constness
  2016-01-11 18:15       ` Nicolai Stange
@ 2016-01-11 19:28         ` Josh Triplett
  2016-12-08  4:48           ` [PATCH] Update maintainers in the manpage Luc Van Oostenryck
  0 siblings, 1 reply; 8+ messages in thread
From: Josh Triplett @ 2016-01-11 19:28 UTC (permalink / raw)
  To: Nicolai Stange; +Cc: Luc Van Oostenryck, linux-sparse

On Mon, Jan 11, 2016 at 07:15:33PM +0100, Nicolai Stange wrote:
> Btw, this remembers me of the fact that Josh Triplett is still listed as
> a maintainer in sparse.1
> 
> Either of {web,man}page is wrong about that. Or both are incomplete and
> we have actually got two maintainers here?

I'm definitely not the maintainer anymore.  I just hang around and
participate sporadically. :)

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

* [PATCH] Update maintainers in the manpage
  2016-01-11 19:28         ` Josh Triplett
@ 2016-12-08  4:48           ` Luc Van Oostenryck
  2016-12-08  5:43             ` Josh Triplett
  0 siblings, 1 reply; 8+ messages in thread
From: Luc Van Oostenryck @ 2016-12-08  4:48 UTC (permalink / raw)
  To: linux-sparse
  Cc: Christopher Li, Nicolai Stange, Luc Van Oostenryck, Josh Triplett

The manpage still mentioned Josh Triplett as the maintainer
while Christopher is the maintainer since 2009.

CC: Christopher Li <sparse@chrisli.org>
CC: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 sparse.1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sparse.1 b/sparse.1
index ccae55cc..4aeb0039 100644
--- a/sparse.1
+++ b/sparse.1
@@ -364,4 +364,4 @@ https://sparse.wiki.kernel.org/
 linux-sparse@vger.kernel.org
 .
 .SH MAINTAINER
-Josh Triplett <josh@kernel.org>
+Christopher Li <sparse@chrisli.org>
-- 
2.10.2


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

* Re: [PATCH] Update maintainers in the manpage
  2016-12-08  4:48           ` [PATCH] Update maintainers in the manpage Luc Van Oostenryck
@ 2016-12-08  5:43             ` Josh Triplett
  0 siblings, 0 replies; 8+ messages in thread
From: Josh Triplett @ 2016-12-08  5:43 UTC (permalink / raw)
  To: Luc Van Oostenryck; +Cc: linux-sparse, Christopher Li, Nicolai Stange

On Thu, Dec 08, 2016 at 05:48:56AM +0100, Luc Van Oostenryck wrote:
> The manpage still mentioned Josh Triplett as the maintainer
> while Christopher is the maintainer since 2009.
> 
> CC: Christopher Li <sparse@chrisli.org>
> CC: Josh Triplett <josh@joshtriplett.org>
> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>

Reviewed-by: Josh Triplett <josh@joshtriplett.org>

>  sparse.1 | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/sparse.1 b/sparse.1
> index ccae55cc..4aeb0039 100644
> --- a/sparse.1
> +++ b/sparse.1
> @@ -364,4 +364,4 @@ https://sparse.wiki.kernel.org/
>  linux-sparse@vger.kernel.org
>  .
>  .SH MAINTAINER
> -Josh Triplett <josh@kernel.org>
> +Christopher Li <sparse@chrisli.org>
> -- 
> 2.10.2
> 

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

end of thread, other threads:[~2016-12-08  5:43 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-22 23:19 [PATCH RFC 07/13] evaluate: check static storage duration objects' intializers' constness Nicolai Stange
2016-01-09 18:04 ` Luc Van Oostenryck
2016-01-09 22:28   ` Nicolai Stange
2016-01-11 18:02     ` Luc Van Oostenryck
2016-01-11 18:15       ` Nicolai Stange
2016-01-11 19:28         ` Josh Triplett
2016-12-08  4:48           ` [PATCH] Update maintainers in the manpage Luc Van Oostenryck
2016-12-08  5:43             ` Josh Triplett

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.