linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] fix handling of address_space in casts and assignments
@ 2007-07-09 22:13 Al Viro
  2007-07-10  1:07 ` [PATCH] fix handling of pointers in ?: Al Viro
  2007-07-12  6:44 ` [PATCH] fix handling of address_space in casts and assignments Josh Triplett
  0 siblings, 2 replies; 4+ messages in thread
From: Al Viro @ 2007-07-09 22:13 UTC (permalink / raw)
  To: linux-sparse

Turn FORCE_MOD into storage class specifier (that's how it's
actually used and that makes for much simpler logics).

Introduce explicit EXPR_FORCE_CAST for forced casts; handle it
properly.

Kill the idiocy in get_as() (we end up picking the oddest things
for address space - e.g. if we have int __attribute__((address_space(1))) *p,
we'll get warnings about removal of address space when we do things like
(unsigned short)*p.  Fixed.  BTW, that had caught a bunch of very odd
bogosities in the kernel and eliminated several false positives in there.

As the result, get_as() is gone now and evaluate_cast() got simpler.

Kill the similar idiocy in handling pointer assignments; while we are at it,
fix the qualifiers check for assignments to/from void * (you can't assign
const int * to void * - qualifiers on the left side should be no less than
on the right one; for normal codepath we get that checked, but the special
case of void * skips these checks).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 compile-i386.c |    1 +
 dissect.c      |    2 +-
 evaluate.c     |   91 +++++++++++++++++++++++---------------------------------
 expand.c       |    1 +
 expression.c   |   18 ++++++++---
 expression.h   |    3 +-
 inline.c       |    1 +
 linearize.c    |    1 +
 parse.c        |    7 +++-
 show-parse.c   |    1 +
 symbol.h       |    4 +-
 11 files changed, 65 insertions(+), 65 deletions(-)

diff --git a/compile-i386.c b/compile-i386.c
index 425a1bc..8526408 100644
--- a/compile-i386.c
+++ b/compile-i386.c
@@ -2351,6 +2351,7 @@ static struct storage *x86_expression(struct expression *expr)
 		warning(expr->pos, "invalid expression after evaluation");
 		return NULL;
 	case EXPR_CAST:
+	case EXPR_FORCE_CAST:
 	case EXPR_IMPLIED_CAST:
 		return emit_cast_expr(expr);
 	case EXPR_VALUE:
diff --git a/dissect.c b/dissect.c
index 9dc3df9..61240d7 100644
--- a/dissect.c
+++ b/dissect.c
@@ -317,7 +317,7 @@ again:
 		do_expression(U_VOID, expr->left);
 		ret = do_expression(mode, expr->right);
 
-	break; case EXPR_CAST: //case EXPR_IMPLIED_CAST:
+	break; case EXPR_CAST: case EXPR_FORCE_CAST: //case EXPR_IMPLIED_CAST:
 		ret = base_type(expr->cast_type);
 		do_initializer(ret, expr->cast_expression);
 
diff --git a/evaluate.c b/evaluate.c
index b97a4d7..d505007 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1276,6 +1276,22 @@ static int compatible_assignment_types(struct expression *expr, struct symbol *t
 				bad_null(*rp);
 			goto Cast;
 		}
+		if (sclass & TYPE_PTR && t->ctype.as == s->ctype.as) {
+			/* we should be more lazy here */
+			int mod1 = t->ctype.modifiers;
+			int mod2 = s->ctype.modifiers;
+			s = get_base_type(s);
+			t = get_base_type(t);
+
+			/*
+			 * assignments to/from void * are OK, provided that
+			 * we do not remove qualifiers from pointed to [C]
+			 * or mix address spaces [sparse].
+			 */
+			if (!(mod2 & ~mod1 & (MOD_VOLATILE | MOD_CONST)))
+				if (s == &void_ctype || t == &void_ctype)
+					goto Cast;
+		}
 	}
 
 	/* It's OK if the target is more volatile or const than the source */
@@ -1283,22 +1299,6 @@ static int compatible_assignment_types(struct expression *expr, struct symbol *t
 	if (!typediff)
 		return 1;
 
-	/* Pointer destination? */
-	if (tclass & TYPE_PTR) {
-		int source_as;
-		int target_as;
-
-		/* "void *" matches anything as long as the address space is OK */
-		target_as = t->ctype.as | target->ctype.as;
-		source_as = s->ctype.as | source->ctype.as;
-		if (source_as == target_as && (s->type == SYM_PTR || s->type == SYM_ARRAY)) {
-			s = get_base_type(s);
-			t = get_base_type(t);
-			if (s == &void_ctype || t == &void_ctype)
-				goto Cast;
-		}
-	}
-
 	warning(expr->pos, "incorrect type in %s (%s)", where, typediff);
 	info(expr->pos, "   expected %s", show_typename(target));
 	info(expr->pos, "   got %s", show_typename(source));
@@ -1330,6 +1330,7 @@ static void mark_assigned(struct expression *expr)
 		mark_assigned(expr->right);
 		return;
 	case EXPR_CAST:
+	case EXPR_FORCE_CAST:
 		mark_assigned(expr->cast_expression);
 		return;
 	case EXPR_SLICE:
@@ -2496,46 +2497,13 @@ static void evaluate_initializer(struct symbol *ctype, struct expression **ep)
 		expression_error(*ep, "invalid initializer");
 }
 
-static int get_as(struct symbol *sym)
-{
-	int as;
-	unsigned long mod;
-
-	if (!sym)
-		return 0;
-	as = sym->ctype.as;
-	mod = sym->ctype.modifiers;
-	if (sym->type == SYM_NODE) {
-		sym = sym->ctype.base_type;
-		as |= sym->ctype.as;
-		mod |= sym->ctype.modifiers;
-	}
-
-	/*
-	 * At least for now, allow casting to a "unsigned long".
-	 * That's how we do things like pointer arithmetic and
-	 * store pointers to registers.
-	 */
-	if (sym == &ulong_ctype)
-		return -1;
-
-	if (sym && sym->type == SYM_PTR) {
-		sym = get_base_type(sym);
-		as |= sym->ctype.as;
-		mod |= sym->ctype.modifiers;
-	}
-	if (mod & MOD_FORCE)
-		return -1;
-	return as;
-}
-
 static struct symbol *evaluate_cast(struct expression *expr)
 {
 	struct expression *target = expr->cast_expression;
 	struct symbol *ctype;
 	struct symbol *t1, *t2;
 	int class1, class2;
-	int as1, as2;
+	int as1 = 0, as2 = 0;
 
 	if (!target)
 		return NULL;
@@ -2596,6 +2564,9 @@ static struct symbol *evaluate_cast(struct expression *expr)
 	if (class1 & TYPE_COMPOUND)
 		warning(expr->pos, "cast to non-scalar");
 
+	if (class1 == TYPE_PTR)
+		get_base_type(t1);
+
 	t2 = target->ctype;
 	if (!t2) {
 		expression_error(expr, "cast from unknown type");
@@ -2606,19 +2577,30 @@ static struct symbol *evaluate_cast(struct expression *expr)
 	if (class2 & TYPE_COMPOUND)
 		warning(expr->pos, "cast from non-scalar");
 
+	if (expr->type == EXPR_FORCE_CAST)
+		goto out;
+
 	/* allowed cast unfouls */
 	if (class2 & TYPE_FOULED)
 		t2 = t2->ctype.base_type;
 
-	if (!(ctype->ctype.modifiers & MOD_FORCE) && t1 != t2) {
+	if (t1 != t2) {
 		if (class1 & TYPE_RESTRICT)
 			warning(expr->pos, "cast to restricted type");
 		if (class2 & TYPE_RESTRICT)
 			warning(expr->pos, "cast from restricted type");
 	}
 
-	as1 = get_as(ctype);
-	as2 = get_as(target->ctype);
+	if (t1 == &ulong_ctype)
+		as1 = -1;
+	else if (class1 == TYPE_PTR)
+		as1 = t1->ctype.as;
+
+	if (t2 == &ulong_ctype)
+		as2 = -1;
+	else if (class2 == TYPE_PTR)
+		as2 = t2->ctype.as;
+
 	if (!as1 && as2 > 0)
 		warning(expr->pos, "cast removes address space of expression");
 	if (as1 > 0 && as2 > 0 && as1 != as2)
@@ -2628,7 +2610,7 @@ static struct symbol *evaluate_cast(struct expression *expr)
 		warning(expr->pos,
 			"cast adds address space to expression (<asn:%d>)", as1);
 
-	if (!(ctype->ctype.modifiers & MOD_PTRINHERIT) && class1 == TYPE_PTR &&
+	if (!(t1->ctype.modifiers & MOD_PTRINHERIT) && class1 == TYPE_PTR &&
 	    !as1 && (target->flags & Int_const_expr)) {
 		if (t1->ctype.base_type == &void_ctype) {
 			if (is_zero_constant(target)) {
@@ -2860,6 +2842,7 @@ struct symbol *evaluate_expression(struct expression *expr)
 			return NULL;
 		return evaluate_postop(expr);
 	case EXPR_CAST:
+	case EXPR_FORCE_CAST:
 	case EXPR_IMPLIED_CAST:
 		return evaluate_cast(expr);
 	case EXPR_SIZEOF:
diff --git a/expand.c b/expand.c
index b2eeef8..06b8127 100644
--- a/expand.c
+++ b/expand.c
@@ -955,6 +955,7 @@ static int expand_expression(struct expression *expr)
 		return expand_postop(expr);
 
 	case EXPR_CAST:
+	case EXPR_FORCE_CAST:
 	case EXPR_IMPLIED_CAST:
 		return expand_cast(expr);
 
diff --git a/expression.c b/expression.c
index 65f959e..77d665d 100644
--- a/expression.c
+++ b/expression.c
@@ -118,7 +118,7 @@ static struct token *parse_type(struct token *token, struct expression **tree)
 	struct symbol *sym;
 	*tree = alloc_expression(token->pos, EXPR_TYPE);
 	(*tree)->flags = Int_const_expr; /* sic */
-	token = typename(token, &sym);
+	token = typename(token, &sym, 0);
 	if (sym->ident)
 		sparse_error(token->pos,
 			     "type expression should not include identifier "
@@ -167,7 +167,7 @@ static struct token *builtin_offsetof_expr(struct token *token,
 		return expect(token, '(', "after __builtin_offset");
 
 	token = token->next;
-	token = typename(token, &sym);
+	token = typename(token, &sym, 0);
 	if (sym->ident)
 		sparse_error(token->pos,
 			     "type expression should not include identifier "
@@ -482,7 +482,7 @@ struct token *primary_expression(struct token *token, struct expression **tree)
 		if (token->special == '[' && lookup_type(token->next)) {
 			expr = alloc_expression(token->pos, EXPR_TYPE);
 			expr->flags = Int_const_expr; /* sic */
-			token = typename(token->next, &expr->symbol);
+			token = typename(token->next, &expr->symbol, 0);
 			token = expect(token, ']', "in type expression");
 			break;
 		}
@@ -600,7 +600,7 @@ static struct token *type_info_expression(struct token *token,
 	token = token->next;
 	if (!match_op(token, '(') || !lookup_type(token->next))
 		return unary_expression(token, &expr->cast_expression);
-	token = typename(token->next, &expr->cast_type);
+	token = typename(token->next, &expr->cast_type, 0);
 
 	if (!match_op(token, ')')) {
 		static const char * error[] = {
@@ -715,15 +715,23 @@ static struct token *cast_expression(struct token *token, struct expression **tr
 			struct expression *cast = alloc_expression(next->pos, EXPR_CAST);
 			struct expression *v;
 			struct symbol *sym;
+			int is_force;
 
-			token = typename(next, &sym);
+			token = typename(next, &sym, MOD_FORCE);
 			cast->cast_type = sym;
+			is_force = sym->ctype.modifiers & MOD_FORCE;
+			sym->ctype.modifiers &= ~MOD_FORCE;
 			token = expect(token, ')', "at end of cast operator");
 			if (match_op(token, '{')) {
+				if (is_force)
+					warning(sym->pos,
+						"[force] in compound literal");
 				token = initializer(&cast->cast_expression, token);
 				return postfix_expression(token, tree, cast);
 			}
 			*tree = cast;
+			if (is_force)
+				cast->type = EXPR_FORCE_CAST;
 			token = cast_expression(token, &v);
 			if (!v)
 				return token;
diff --git a/expression.h b/expression.h
index 02eec02..fa5039a 100644
--- a/expression.h
+++ b/expression.h
@@ -27,6 +27,7 @@ enum expression_type {
 	EXPR_PREOP,
 	EXPR_POSTOP,
 	EXPR_CAST,
+	EXPR_FORCE_CAST,
 	EXPR_IMPLIED_CAST,
 	EXPR_SIZEOF,
 	EXPR_ALIGNOF,
@@ -190,7 +191,7 @@ static inline struct expression *alloc_const_expression(struct position pos, int
 }
 
 /* Type name parsing */
-struct token *typename(struct token *, struct symbol **);
+struct token *typename(struct token *, struct symbol **, int);
 
 static inline int lookup_type(struct token *token)
 {
diff --git a/inline.c b/inline.c
index 061261a..860c0ee 100644
--- a/inline.c
+++ b/inline.c
@@ -145,6 +145,7 @@ static struct expression * copy_expression(struct expression *expr)
 			*expr->cast_type = *sym;
 			break;
 		}
+	case EXPR_FORCE_CAST:
 	case EXPR_IMPLIED_CAST:
 	case EXPR_SIZEOF: 
 	case EXPR_PTRSIZEOF:
diff --git a/linearize.c b/linearize.c
index 3a07823..8a68f05 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1581,6 +1581,7 @@ pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr)
 		return linearize_postop(ep, expr);
 
 	case EXPR_CAST:
+	case EXPR_FORCE_CAST:
 	case EXPR_IMPLIED_CAST:
 		return linearize_cast(ep, expr);
 	
diff --git a/parse.c b/parse.c
index ab3a096..68f1dac 100644
--- a/parse.c
+++ b/parse.c
@@ -768,7 +768,7 @@ static struct token *typeof_specifier(struct token *token, struct ctype *ctype)
 		return token;
 	}
 	if (lookup_type(token->next)) {
-		token = typename(token->next, &sym);
+		token = typename(token->next, &sym, 0);
 		*ctype = sym->ctype;
 	} else {
 		struct symbol *typeof_sym = alloc_symbol(token->pos, SYM_TYPEOF);
@@ -1343,13 +1343,16 @@ static struct token *parameter_declaration(struct token *token, struct symbol **
 	return token;
 }
 
-struct token *typename(struct token *token, struct symbol **p)
+struct token *typename(struct token *token, struct symbol **p, int mod)
 {
 	struct symbol *sym = alloc_symbol(token->pos, SYM_NODE);
 	*p = sym;
 	token = declaration_specifiers(token, &sym->ctype, 0);
 	token = declarator(token, sym, NULL);
 	apply_modifiers(token->pos, &sym->ctype);
+	if (sym->ctype.modifiers & MOD_STORAGE & ~mod)
+		warning(sym->pos, "storage class in typename (%s)",
+			show_typename(sym));
 	return token;
 }
 
diff --git a/show-parse.c b/show-parse.c
index 07ee763..aae8b74 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -1053,6 +1053,7 @@ int show_expression(struct expression *expr)
 		warning(expr->pos, "invalid expression after evaluation");
 		return 0;
 	case EXPR_CAST:
+	case EXPR_FORCE_CAST:
 	case EXPR_IMPLIED_CAST:
 		return show_cast_expr(expr);
 	case EXPR_VALUE:
diff --git a/symbol.h b/symbol.h
index a59feee..4d8d328 100644
--- a/symbol.h
+++ b/symbol.h
@@ -204,12 +204,12 @@ struct symbol {
 #define MOD_BITWISE	0x80000000
 
 #define MOD_NONLOCAL	(MOD_EXTERN | MOD_TOPLEVEL)
-#define MOD_STORAGE	(MOD_AUTO | MOD_REGISTER | MOD_STATIC | MOD_EXTERN | MOD_INLINE | MOD_TOPLEVEL)
+#define MOD_STORAGE	(MOD_AUTO | MOD_REGISTER | MOD_STATIC | MOD_EXTERN | MOD_INLINE | MOD_TOPLEVEL | MOD_FORCE)
 #define MOD_SIGNEDNESS	(MOD_SIGNED | MOD_UNSIGNED | MOD_EXPLICITLY_SIGNED)
 #define MOD_SPECIFIER	(MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG | MOD_SIGNEDNESS)
 #define MOD_SIZE	(MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG)
 #define MOD_IGNORE (MOD_TOPLEVEL | MOD_STORAGE | MOD_ADDRESSABLE |	\
-	MOD_ASSIGNED | MOD_USERTYPE | MOD_FORCE | MOD_ACCESSED | MOD_EXPLICITLY_SIGNED)
+	MOD_ASSIGNED | MOD_USERTYPE | MOD_ACCESSED | MOD_EXPLICITLY_SIGNED)
 #define MOD_PTRINHERIT (MOD_VOLATILE | MOD_CONST | MOD_NODEREF | MOD_STORAGE)
 
 
-- 
1.5.0-rc2.GIT

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

* [PATCH] fix handling of pointers in ?:
  2007-07-09 22:13 [PATCH] fix handling of address_space in casts and assignments Al Viro
@ 2007-07-10  1:07 ` Al Viro
  2007-07-12  6:44   ` Josh Triplett
  2007-07-12  6:44 ` [PATCH] fix handling of address_space in casts and assignments Josh Triplett
  1 sibling, 1 reply; 4+ messages in thread
From: Al Viro @ 2007-07-10  1:07 UTC (permalink / raw)
  To: linux-sparse

a) qualifiers are joined (const int * / volatile int * -> const volatile int *)
b) pointer to void / pointer to T => pointer to void (with all qualifiers)

testcase added

Still missing: T1 * / T2 * => pointer to composite type of T1 and T2

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 evaluate.c              |   82 ++++++++++++++++++++++++++++-------------------
 validation/cond_expr2.c |   23 +++++++++++++
 2 files changed, 72 insertions(+), 33 deletions(-)
 create mode 100644 validation/cond_expr2.c

diff --git a/evaluate.c b/evaluate.c
index d505007..9f543fe 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1070,31 +1070,6 @@ OK:
 }
 
 /*
- * FIXME!! This should do casts, array degeneration etc..
- */
-static struct symbol *compatible_ptr_type(struct expression *left, struct expression *right)
-{
-	struct symbol *ltype = left->ctype, *rtype = right->ctype;
-
-	if (ltype->type == SYM_NODE)
-		ltype = ltype->ctype.base_type;
-
-	if (rtype->type == SYM_NODE)
-		rtype = rtype->ctype.base_type;
-
-	if (ltype->type == SYM_PTR) {
-		if (rtype->ctype.base_type == &void_ctype)
-			return ltype;
-	}
-
-	if (rtype->type == SYM_PTR) {
-		if (ltype->ctype.base_type == &void_ctype)
-			return rtype;
-	}
-	return NULL;
-}
-
-/*
  * NOTE! The degenerate case of "x ? : y", where we don't
  * have a true case, this will possibly promote "x" to the
  * same type as "y", and thus _change_ the conditional
@@ -1104,9 +1079,10 @@ static struct symbol *compatible_ptr_type(struct expression *left, struct expres
 static struct symbol *evaluate_conditional_expression(struct expression *expr)
 {
 	struct expression **true;
-	struct symbol *ctype, *ltype, *rtype;
+	struct symbol *ctype, *ltype, *rtype, *lbase, *rbase;
 	int lclass, rclass;
 	const char * typediff;
+	int qual;
 
 	if (!evaluate_conditional(expr->conditional, 0))
 		return NULL;
@@ -1141,9 +1117,11 @@ static struct symbol *evaluate_conditional_expression(struct expression *expr)
 		expr->cond_false = cast_to(expr->cond_false, ctype);
 		goto out;
 	}
+
 	if ((lclass | rclass) & TYPE_PTR) {
 		int is_null1 = is_null_pointer_constant(*true);
 		int is_null2 = is_null_pointer_constant(expr->cond_false);
+
 		if (is_null1 && is_null2) {
 			*true = cast_to(*true, &ptr_ctype);
 			expr->cond_false = cast_to(expr->cond_false, &ptr_ctype);
@@ -1169,15 +1147,42 @@ static struct symbol *evaluate_conditional_expression(struct expression *expr)
 			goto Err;
 		}
 		/* OK, it's pointer on pointer */
-		/* XXX - we need to handle qualifiers */
-		ctype = compatible_ptr_type(*true, expr->cond_false);
-		if (ctype)
-			goto out;
+		if (ltype->ctype.as != rtype->ctype.as) {
+			typediff = "different address spaces";
+			goto Err;
+		}
+
+		/* need to be lazier here */
+		lbase = get_base_type(ltype);
+		rbase = get_base_type(rtype);
+		qual = ltype->ctype.modifiers | rtype->ctype.modifiers;
+		qual &= MOD_CONST | MOD_VOLATILE;
+
+		if (lbase == &void_ctype) {
+			/* XXX: pointers to function should warn here */
+			ctype = ltype;
+			goto Qual;
+
+		}
+		if (rbase == &void_ctype) {
+			/* XXX: pointers to function should warn here */
+			ctype = rtype;
+			goto Qual;
+		}
+		/* XXX: that should be pointer to composite */
+		ctype = ltype;
+		typediff = type_difference(lbase, rbase, MOD_IGN, MOD_IGN);
+		if (!typediff)
+			goto Qual;
+		goto Err;
 	}
-	ctype = ltype;
-	typediff = type_difference(ltype, rtype, MOD_IGN, MOD_IGN);
-	if (!typediff)
+
+	/* void on void, struct on same struct, union on same union */
+	if (ltype == rtype) {
+		ctype = ltype;
 		goto out;
+	}
+	typediff = "different base types";
 
 Err:
 	expression_error(expr, "incompatible types in conditional expression (%s)", typediff);
@@ -1186,6 +1191,17 @@ Err:
 out:
 	expr->ctype = ctype;
 	return ctype;
+
+Qual:
+	if (qual & ~ctype->ctype.modifiers) {
+		struct symbol *sym = alloc_symbol(ctype->pos, SYM_PTR);
+		*sym = *ctype;
+		sym->ctype.modifiers |= qual;
+		ctype = sym;
+	}
+	*true = cast_to(*true, ctype);
+	expr->cond_false = cast_to(expr->cond_false, ctype);
+	goto out;
 }
 
 /* FP assignments can not do modulo or bit operations */
diff --git a/validation/cond_expr2.c b/validation/cond_expr2.c
new file mode 100644
index 0000000..e53cd13
--- /dev/null
+++ b/validation/cond_expr2.c
@@ -0,0 +1,23 @@
+extern const int *p;
+extern volatile void *q;
+extern volatile int *r;
+static void f(void)
+{
+	q = 1 ? p : q;	// warn: const volatile void * -> const int *
+	r = 1 ? r : q;	// OK: volatile void * -> volatile int *
+	r = 1 ? r : p;	// warn: const volatile int * -> volatile int *
+}
+/*
+ * check-name: type of conditional expression
+ * check-description: Used to miss qualifier mixing and mishandle void *
+ * check-command: sparse $file
+ *
+ * check-output-start
+cond_expr2.c:6:4: warning: incorrect type in assignment (different modifiers)
+cond_expr2.c:6:4:    expected void volatile *extern [addressable] [toplevel] q
+cond_expr2.c:6:4:    got void const volatile *
+cond_expr2.c:8:4: warning: incorrect type in assignment (different modifiers)
+cond_expr2.c:8:4:    expected int volatile *extern [addressable] [toplevel] [assigned] r
+cond_expr2.c:8:4:    got int const volatile *
+ * check-output-end
+ */
-- 
1.5.0-rc2.GIT

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

* Re: [PATCH] fix handling of address_space in casts and assignments
  2007-07-09 22:13 [PATCH] fix handling of address_space in casts and assignments Al Viro
  2007-07-10  1:07 ` [PATCH] fix handling of pointers in ?: Al Viro
@ 2007-07-12  6:44 ` Josh Triplett
  1 sibling, 0 replies; 4+ messages in thread
From: Josh Triplett @ 2007-07-12  6:44 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-sparse

[-- Attachment #1: Type: text/plain, Size: 1087 bytes --]

Al Viro wrote:
> Turn FORCE_MOD into storage class specifier (that's how it's
> actually used and that makes for much simpler logics).
> 
> Introduce explicit EXPR_FORCE_CAST for forced casts; handle it
> properly.
> 
> Kill the idiocy in get_as() (we end up picking the oddest things
> for address space - e.g. if we have int __attribute__((address_space(1))) *p,
> we'll get warnings about removal of address space when we do things like
> (unsigned short)*p.  Fixed.  BTW, that had caught a bunch of very odd
> bogosities in the kernel and eliminated several false positives in there.
> 
> As the result, get_as() is gone now and evaluate_cast() got simpler.
> 
> Kill the similar idiocy in handling pointer assignments; while we are at it,
> fix the qualifiers check for assignments to/from void * (you can't assign
> const int * to void * - qualifiers on the left side should be no less than
> on the right one; for normal codepath we get that checked, but the special
> case of void * skips these checks).

Applied (yesterday); thanks!

- Josh Triplett



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]

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

* Re: [PATCH] fix handling of pointers in ?:
  2007-07-10  1:07 ` [PATCH] fix handling of pointers in ?: Al Viro
@ 2007-07-12  6:44   ` Josh Triplett
  0 siblings, 0 replies; 4+ messages in thread
From: Josh Triplett @ 2007-07-12  6:44 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-sparse

[-- Attachment #1: Type: text/plain, Size: 254 bytes --]

Al Viro wrote:
> a) qualifiers are joined (const int * / volatile int * -> const volatile int *)
> b) pointer to void / pointer to T => pointer to void (with all qualifiers)
> 
> testcase added

Applied (yesterday); thanks!

- Josh Triplett



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]

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

end of thread, other threads:[~2007-07-12  6:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-09 22:13 [PATCH] fix handling of address_space in casts and assignments Al Viro
2007-07-10  1:07 ` [PATCH] fix handling of pointers in ?: Al Viro
2007-07-12  6:44   ` Josh Triplett
2007-07-12  6:44 ` [PATCH] fix handling of address_space in casts and assignments Josh Triplett

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).