linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] saner warnings for restricted types
@ 2008-01-15 16:52 Al Viro
  2008-01-15 17:36 ` Pavel Roskin
  0 siblings, 1 reply; 5+ messages in thread
From: Al Viro @ 2008-01-15 16:52 UTC (permalink / raw)
  To: linux-sparse

* don't crap the type->ident for unsigned int just because somebody did
	typedef unsigned int x;
  only structs, unions, enums and restricted types need this logics.
* generate saner warnings for restricted, include type name(s) into them.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 evaluate.c   |   33 ++++++++++++++++++++-------------
 parse.c      |   11 +++++++++--
 show-parse.c |    4 ++++
 3 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/evaluate.c b/evaluate.c
index 54fcd3f..777f603 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -500,9 +500,10 @@ static inline void unrestrict(struct expression *expr,
 			      int class, struct symbol **ctype)
 {
 	if (class & TYPE_RESTRICT) {
-		warning(expr->pos, "restricted degrades to integer");
 		if (class & TYPE_FOULED)
 			*ctype = unfoul(*ctype);
+		warning(expr->pos, "%sdegrades to integer",
+			show_typename(*ctype));
 		*ctype = (*ctype)->ctype.base_type; /* get to arithmetic type */
 	}
 }
@@ -1235,7 +1236,9 @@ static int evaluate_assign_op(struct expression *expr)
 		}
 		if (tclass & TYPE_RESTRICT) {
 			if (!restricted_binop(op, t)) {
-				expression_error(expr, "bad restricted assignment");
+				warning(expr->pos, "bad assignment (%s) to %s",
+					show_special(op), show_typename(t));
+				expr->right = cast_to(expr->right, target);
 				return 0;
 			}
 			/* allowed assignments unfoul */
@@ -1248,7 +1251,9 @@ static int evaluate_assign_op(struct expression *expr)
 		/* source and target would better be identical restricted */
 		if (t == s)
 			return 1;
-		warning(expr->pos, "invalid restricted assignment");
+		warning(expr->pos, "invalid assignment: %s", show_special(op));
+		info(expr->pos, "   left side has type %s", show_typename(t));
+		info(expr->pos, "   right side has type %s", show_typename(s));
 		expr->right = cast_to(expr->right, target);
 		return 0;
 	}
@@ -1707,10 +1712,8 @@ static struct symbol *evaluate_postop(struct expression *expr)
 		return NULL;
 	}
 
-	if ((class & TYPE_RESTRICT) && restricted_unop(expr->op, &ctype)) {
-		expression_error(expr, "bad operation on restricted");
-		return NULL;
-	}
+	if ((class & TYPE_RESTRICT) && restricted_unop(expr->op, &ctype))
+		return bad_expr_type(expr);
 
 	if (class & TYPE_NUM) {
 		multiply = 1;
@@ -1799,7 +1802,8 @@ static struct symbol *evaluate_preop(struct expression *expr)
 			expr->right->ctype = ctype;
 			expr->right->fvalue = 0;
 		} else if (is_fouled_type(ctype)) {
-			warning(expr->pos, "restricted degrades to integer");
+			warning(expr->pos, "%sdegrades to integer",
+				show_typename(ctype->ctype.base_type));
 		}
 		ctype = &bool_ctype;
 		break;
@@ -2664,9 +2668,11 @@ static struct symbol *evaluate_cast(struct expression *expr)
 
 	if (t1 != t2) {
 		if (class1 & TYPE_RESTRICT)
-			warning(expr->pos, "cast to restricted type");
+			warning(expr->pos, "cast to %s",
+				show_typename(t1));
 		if (class2 & TYPE_RESTRICT)
-			warning(expr->pos, "cast from restricted type");
+			warning(expr->pos, "cast from %s",
+				show_typename(t2));
 	}
 
 	if (t1 == &ulong_ctype)
@@ -3246,9 +3252,10 @@ static void check_case_type(struct expression *switch_expr,
 		return;
 
 	if (!restricted_binop_type(SPECIAL_EQUAL, case_expr, switch_expr,
-				   cclass, sclass, case_type, switch_type))
-		warning(case_expr->pos, "restricted degrades to integer");
-
+				   cclass, sclass, case_type, switch_type)) {
+		unrestrict(case_expr, cclass, &case_type);
+		unrestrict(switch_expr, sclass, &switch_type);
+	}
 	return;
 
 Bad:
diff --git a/parse.c b/parse.c
index a41939d..6255737 100644
--- a/parse.c
+++ b/parse.c
@@ -2158,8 +2158,15 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
 	base_type = decl->ctype.base_type;
 
 	if (is_typedef) {
-		if (base_type && !base_type->ident)
-			base_type->ident = ident;
+		if (base_type && !base_type->ident) {
+			switch (base_type->type) {
+			case SYM_STRUCT:
+			case SYM_UNION:
+			case SYM_ENUM:
+			case SYM_RESTRICT:
+				base_type->ident = ident;
+			}
+		}
 	} else if (base_type && base_type->type == SYM_FN) {
 		/* K&R argument declaration? */
 		if (lookup_type(token))
diff --git a/show-parse.c b/show-parse.c
index 9a1f796..b9a2828 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -309,6 +309,10 @@ static void do_show_type(struct symbol *sym, struct type_name *name,
 		break;
 
 	case SYM_RESTRICT:
+		if (sym->ident) {
+			prepend(name, "restricted %s ", show_ident(sym->ident));
+			return;
+		}
 		break;
 
 	case SYM_FOULED:
-- 
1.5.3.GIT

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

* Re: [PATCH] saner warnings for restricted types
  2008-01-15 16:52 [PATCH] saner warnings for restricted types Al Viro
@ 2008-01-15 17:36 ` Pavel Roskin
  2008-01-15 18:58   ` Al Viro
  0 siblings, 1 reply; 5+ messages in thread
From: Pavel Roskin @ 2008-01-15 17:36 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-sparse

On Tue, 2008-01-15 at 16:52 +0000, Al Viro wrote:
>  	if (class & TYPE_RESTRICT) {
> -		warning(expr->pos, "restricted degrades to integer");
>  		if (class & TYPE_FOULED)
>  			*ctype = unfoul(*ctype);
> +		warning(expr->pos, "%sdegrades to integer",
> +			show_typename(*ctype));

Missing space after "%s"?

-- 
Regards,
Pavel Roskin

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

* Re: [PATCH] saner warnings for restricted types
  2008-01-15 17:36 ` Pavel Roskin
@ 2008-01-15 18:58   ` Al Viro
  2008-01-15 21:04     ` Pavel Roskin
  2008-01-15 23:14     ` Al Viro
  0 siblings, 2 replies; 5+ messages in thread
From: Al Viro @ 2008-01-15 18:58 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: linux-sparse

On Tue, Jan 15, 2008 at 12:36:12PM -0500, Pavel Roskin wrote:
> On Tue, 2008-01-15 at 16:52 +0000, Al Viro wrote:
> >  	if (class & TYPE_RESTRICT) {
> > -		warning(expr->pos, "restricted degrades to integer");
> >  		if (class & TYPE_FOULED)
> >  			*ctype = unfoul(*ctype);
> > +		warning(expr->pos, "%sdegrades to integer",
> > +			show_typename(*ctype));
> 
> Missing space after "%s"?

No.  Try it and you'll see...  The way show_typename() (actually, the
stuff behind it) works you get a space after the damn thing.  What you'll
get is something like

kernel/power/main.c:242:2: warning: restricted suspend_state_t degrades to integer

Actually, if you look at the things like

fs/afs/fsclient.c:465:21: warning: incorrect type in assignment (different base types)
fs/afs/fsclient.c:465:21:    expected restricted __be32 [usertype] operation_ID
fs/afs/fsclient.c:465:21:    got int

you'll see that the last line is "fs/afs/fsclient.c:465:21:    got int \n" -
with whitespace in the end.  We could get rid of that, but it'll take more
massage and it's definitely a separate patch series.

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

* Re: [PATCH] saner warnings for restricted types
  2008-01-15 18:58   ` Al Viro
@ 2008-01-15 21:04     ` Pavel Roskin
  2008-01-15 23:14     ` Al Viro
  1 sibling, 0 replies; 5+ messages in thread
From: Pavel Roskin @ 2008-01-15 21:04 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-sparse


On Tue, 2008-01-15 at 18:58 +0000, Al Viro wrote:
> On Tue, Jan 15, 2008 at 12:36:12PM -0500, Pavel Roskin wrote:
> > On Tue, 2008-01-15 at 16:52 +0000, Al Viro wrote:
> > >  	if (class & TYPE_RESTRICT) {
> > > -		warning(expr->pos, "restricted degrades to integer");
> > >  		if (class & TYPE_FOULED)
> > >  			*ctype = unfoul(*ctype);
> > > +		warning(expr->pos, "%sdegrades to integer",
> > > +			show_typename(*ctype));
> > 
> > Missing space after "%s"?
> 
> No.  Try it and you'll see...

OK, just wanted to make sure.  Thanks for the explanation!

-- 
Regards,
Pavel Roskin

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

* Re: [PATCH] saner warnings for restricted types
  2008-01-15 18:58   ` Al Viro
  2008-01-15 21:04     ` Pavel Roskin
@ 2008-01-15 23:14     ` Al Viro
  1 sibling, 0 replies; 5+ messages in thread
From: Al Viro @ 2008-01-15 23:14 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: linux-sparse

On Tue, Jan 15, 2008 at 06:58:56PM +0000, Al Viro wrote:
> with whitespace in the end.  We could get rid of that, but it'll take more
> massage and it's definitely a separate patch series.

Whee...

; cat >foo.c <<'EOF'
int a[2][3];
EOF
; test-parsing foo.c
foo.c:1:5: warning: symbol 'a' was not declared. Should it be static?
.align 4
int [addressable] [toplevel] a[3][2]
;

See that [3][2]?  IOW, show_typename() really needs fixing.  Oh, well...

The problem is that append() part should go *before* recursive call, not
after it.  We want appended stuff from the outer levels closer to the
center (i.e. to the name if it's present).  Anyway, the fix follows:

[PATCH] fix show_typename()

* postfix stuff had been added in the wrong order (e.g. int a[2][3] generated
int [addressable][toplevel] a[3][2])
* after fixing that, we've no need for recursion anymore, a bunch of arguments
go away and turn into local variables and we get an easy way to get rid of
bogus space in the show_typename() result.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 evaluate.c   |    4 +-
 show-parse.c |  100 +++++++++++++++++++++++++++++----------------------------
 2 files changed, 53 insertions(+), 51 deletions(-)

diff --git a/evaluate.c b/evaluate.c
index 777f603..2901c1b 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -502,7 +502,7 @@ static inline void unrestrict(struct expression *expr,
 	if (class & TYPE_RESTRICT) {
 		if (class & TYPE_FOULED)
 			*ctype = unfoul(*ctype);
-		warning(expr->pos, "%sdegrades to integer",
+		warning(expr->pos, "%s degrades to integer",
 			show_typename(*ctype));
 		*ctype = (*ctype)->ctype.base_type; /* get to arithmetic type */
 	}
@@ -1802,7 +1802,7 @@ static struct symbol *evaluate_preop(struct expression *expr)
 			expr->right->ctype = ctype;
 			expr->right->fvalue = 0;
 		} else if (is_fouled_type(ctype)) {
-			warning(expr->pos, "%sdegrades to integer",
+			warning(expr->pos, "%s degrades to integer",
 				show_typename(ctype->ctype.base_type));
 		}
 		ctype = &bool_ctype;
diff --git a/show-parse.c b/show-parse.c
index b9a2828..064af32 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -226,12 +226,16 @@ const char *builtin_ctypename(struct ctype *ctype)
 	return NULL;
 }
 
-static void do_show_type(struct symbol *sym, struct type_name *name,
-			 unsigned long mod, int as, int was_ptr)
+static void do_show_type(struct symbol *sym, struct type_name *name)
 {
 	const char *typename;
-	int is_ptr = was_ptr;
+	unsigned long mod = 0;
+	int as = 0;
+	int was_ptr = 0;
+	int restr = 0;
+	int fouled = 0;
 
+deeper:
 	if (!sym || (sym->type != SYM_NODE && sym->type != SYM_ARRAY &&
 		     sym->type != SYM_BITFIELD)) {
 		const char *s;
@@ -249,14 +253,15 @@ static void do_show_type(struct symbol *sym, struct type_name *name,
 	}
 
 	if (!sym)
-		return;
+		goto out;
 
 	if ((typename = builtin_typename(sym))) {
 		int len = strlen(typename);
-		*--name->start = ' ';
+		if (name->start != name->end)
+			*--name->start = ' ';
 		name->start -= len;
 		memcpy(name->start, typename, len);
-		return;
+		goto out;
 	}
 
 	/* Prepend */
@@ -265,20 +270,29 @@ static void do_show_type(struct symbol *sym, struct type_name *name,
 		prepend(name, "*");
 		mod = sym->ctype.modifiers;
 		as = sym->ctype.as;
-		is_ptr = 1;
+		was_ptr = 1;
 		break;
+
 	case SYM_FN:
-		if (was_ptr)
+		if (was_ptr) {
 			prepend(name, "( ");
-		is_ptr = 0;
+			append(name, " )");
+			was_ptr = 0;
+		}
+		append(name, "( ... )");
 		break;
+
 	case SYM_STRUCT:
-		prepend(name, "struct %s ", show_ident(sym->ident));
-		return;
+		if (name->start != name->end)
+			*--name->start = ' ';
+		prepend(name, "struct %s", show_ident(sym->ident));
+		goto out;
 
 	case SYM_UNION:
-		prepend(name, "union %s ", show_ident(sym->ident));
-		return;
+		if (name->start != name->end)
+			*--name->start = ' ';
+		prepend(name, "union %s", show_ident(sym->ident));
+		goto out;
 
 	case SYM_ENUM:
 		prepend(name, "enum %s ", show_ident(sym->ident));
@@ -298,60 +312,48 @@ static void do_show_type(struct symbol *sym, struct type_name *name,
 
 	case SYM_LABEL:
 		append(name, "label(%s:%p)", show_ident(sym->ident), sym);
-		break;
+		return;
 
 	case SYM_ARRAY:
 		mod |= sym->ctype.modifiers;
 		as |= sym->ctype.as;
-		if (was_ptr)
+		if (was_ptr) {
 			prepend(name, "( ");
-		is_ptr = 0;
+			append(name, " )");
+			was_ptr = 0;
+		}
+		append(name, "[%lld]", get_expression_value(sym->array_size));
 		break;
 
 	case SYM_RESTRICT:
-		if (sym->ident) {
-			prepend(name, "restricted %s ", show_ident(sym->ident));
-			return;
+		if (!sym->ident) {
+			restr = 1;
+			break;
 		}
-		break;
+		if (name->start != name->end)
+			*--name->start = ' ';
+		prepend(name, "restricted %s", show_ident(sym->ident));
+		goto out;
 
 	case SYM_FOULED:
+		fouled = 1;
 		break;
 
 	default:
+		if (name->start != name->end)
+			*--name->start = ' ';
 		prepend(name, "unknown type %d", sym->type);
-		return;
+		goto out;
 	}
 
-	do_show_type(sym->ctype.base_type, name, mod, as, is_ptr);
-
-	switch (sym->type) {
-	case SYM_PTR:
-		return;
-
-	case SYM_FN:
-		if (was_ptr)
-			append(name, " )");
-		append(name, "( ... )");
-		return;
-
-	case SYM_ARRAY:
-		if (was_ptr)
-			append(name, " )");
-		append(name, "[%lld]", get_expression_value(sym->array_size));
-		return;
+	sym = sym->ctype.base_type;
+	goto deeper;
 
-	case SYM_RESTRICT:
+out:
+	if (restr)
 		prepend(name, "restricted ");
-		return;
-
-	case SYM_FOULED:
+	if (fouled)
 		prepend(name, "fouled ");
-		return;
-
-	default:
-		break;
-	}
 }
 
 void show_type(struct symbol *sym)
@@ -360,7 +362,7 @@ void show_type(struct symbol *sym)
 	struct type_name name;
 
 	name.start = name.end = array+100;
-	do_show_type(sym, &name, 0, 0, 0);
+	do_show_type(sym, &name);
 	*name.end = 0;
 	printf("%s", name.start);
 }
@@ -371,7 +373,7 @@ const char *show_typename(struct symbol *sym)
 	struct type_name name;
 
 	name.start = name.end = array+100;
-	do_show_type(sym, &name, 0, 0, 0);
+	do_show_type(sym, &name);
 	*name.end = 0;
 	return name.start;
 }
-- 
1.5.3.GIT

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

end of thread, other threads:[~2008-01-15 23:14 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-15 16:52 [PATCH] saner warnings for restricted types Al Viro
2008-01-15 17:36 ` Pavel Roskin
2008-01-15 18:58   ` Al Viro
2008-01-15 21:04     ` Pavel Roskin
2008-01-15 23:14     ` Al Viro

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).