Skip to contentSkip to conversation

fix the comma handling in integer constant expressions

PATCH In review Al Viro 2 participants 2 messages Jul 1, 2007 – Jul 9, 2007 Sparse checker

lore
Share & tools
lore

Al Viro

author
#0 lore raw

PATCH 1/1 fix the comma handling in integer constant expressions

[my apologies to the folks on Cc, original mails got the list address buggered in To:, thus the resend of the entire series just to the list]

Quoted 4 lines · Al Viro

... or it could be done simpler, if we keep the current logics for Int_const_expr flag at parse time and add a 'const expression' one with rules as above. Anyway, I'm going to get some sleep before dealing with that crap.

From: Al Viro <[email protected]>
Date: Sun, 1 Jul 2007 02:28:10 -0400
Subject: [PATCH] fix the comma handling in integer constant expressions

Treat it as normal binary operation, taint the value, check the taint. We can do other kind of value tainting with the same infrastructure as well...

Review and testing would be welcome; AFAICS, it works, but...

---
 evaluate.c   |    6 ++++++
 expand.c     |   41 ++++++++++++++++++++++++++++++++++++++---
 expression.c |   14 +++-----------
 expression.h |    9 ++++++++-
 symbol.c     |    1 +
 5 files changed, 56 insertions(+), 15 deletions(-)
evaluate.c +6 -0
index bcac1d2..3156e9d 100644
@@ -956,6 +956,7 @@ static struct symbol *evaluate_binop(struct expression *expr)
 static struct symbol *evaluate_comma(struct expression *expr)
 {
 	expr->ctype = expr->right->ctype;
+	expr->flags &= expr->left->flags & expr->right->flags;
 	return expr->ctype;
 }
 
@@ -1859,6 +1860,7 @@ static struct symbol *evaluate_sizeof(struct expression *expr)
 		expression_error(expr, "cannot size expression");
 	expr->type = EXPR_VALUE;
 	expr->value = size >> 3;
+	expr->taint = 0;
 	expr->ctype = size_t_ctype;
 	return size_t_ctype;
 }
@@ -1892,6 +1894,7 @@ static struct symbol *evaluate_ptrsizeof(struct expression *expr)
 		size = 0;
 	expr->type = EXPR_VALUE;
 	expr->value = size >> 3;
+	expr->taint = 0;
 	expr->ctype = size_t_ctype;
 	return size_t_ctype;
 }
@@ -1906,6 +1909,7 @@ static struct symbol *evaluate_alignof(struct expression *expr)
 
 	expr->type = EXPR_VALUE;
 	expr->value = type->ctype.alignment;
+	expr->taint = 0;
 	expr->ctype = size_t_ctype;
 	return size_t_ctype;
 }
@@ -2675,6 +2679,7 @@ static struct symbol *evaluate_offsetof(struct expression *expr)
 		expr->type = EXPR_VALUE;
 		expr->flags = Int_const_expr;
 		expr->value = offset;
+		expr->taint = 0;
 		expr->ctype = size_t_ctype;
 	} else {
 		if (!ctype) {
@@ -2692,6 +2697,7 @@ static struct symbol *evaluate_offsetof(struct expression *expr)
 			expr->type = EXPR_VALUE;
 			expr->flags = Int_const_expr;
 			expr->value = 0;
+			expr->taint = 0;
 			expr->ctype = size_t_ctype;
 		} else {
 			struct expression *idx = expr->index, *m;
expand.c +38 -3

155 lines not on this page · raw message

expression.c +3 -11
index d36c3d2..65f959e 100644
@@ -751,7 +751,7 @@ static struct token *cast_expression(struct token *token, struct expression **tr
  * than create a data structure for it.
  */
 
-#define __LR_BINOP_EXPRESSION(__token, tree, type, inner, compare, is_const)	\
+#define LR_BINOP_EXPRESSION(__token, tree, type, inner, compare)	\
 	struct expression *left = NULL;					\
 	struct token * next = inner(__token, &left);			\
 									\
@@ -768,8 +768,7 @@ static struct token *cast_expression(struct token *token, struct expression **tr
 				sparse_error(next->pos, "No right hand side of '%s'-expression", show_special(op));	\
 				break;					\
 			}						\
-			if (is_const)					\
-				top->flags = left->flags & right->flags \
+			top->flags = left->flags & right->flags		\
 						& Int_const_expr;	\
 			top->op = op;					\
 			top->left = left;				\
@@ -781,13 +780,6 @@ out:									\
 	*tree = left;							\
 	return next;							\
 
-#define LR_BINOP_EXPRESSION(token, tree, type, inner, compare) \
-	__LR_BINOP_EXPRESSION((token), (tree), (type), (inner), (compare), 1)
-
-#define LR_BINOP_EXPRESSION_NONCONST(token, tree, type, inner, compare) \
-	__LR_BINOP_EXPRESSION((token), (tree), (type), (inner), (compare), 0)
-
-
 static struct token *multiplicative_expression(struct token *token, struct expression **tree)
 {
 	LR_BINOP_EXPRESSION(
@@ -918,7 +910,7 @@ struct token *assignment_expression(struct token *token, struct expression **tre
 
 static struct token *comma_expression(struct token *token, struct expression **tree)
 {
-	LR_BINOP_EXPRESSION_NONCONST(
+	LR_BINOP_EXPRESSION(
 		token, tree, EXPR_COMMA, assignment_expression,
 		(op == ',')
 	);
expression.h +8 -1
index a913153..23ca408 100644
@@ -52,6 +52,10 @@ enum {
 	Float_literal = 2,
 }; /* for expr->flags */
 
+enum {
+	Taint_comma = 1,
+};
+
 struct expression {
 	enum expression_type type:8;
 	unsigned flags:8;
@@ -60,7 +64,10 @@ struct expression {
 	struct symbol *ctype;
 	union {
 		// EXPR_VALUE
-		unsigned long long value;
+		struct {
+			unsigned long long value;
+			unsigned taint;
+		};
 
 		// EXPR_FVALUE
 		long double fvalue;
symbol.c +1 -0
index 329fed9..cec7e02 100644
@@ -652,6 +652,7 @@ static int expand_warning(struct expression *expr, int cost)
 out:
 	expr->type = EXPR_VALUE;
 	expr->value = 1;
+	expr->taint = 0;
 	return 0;
 }
 
Signature · 1 line
1.5.0-rc2.GIT
#1 lore raw
Quoted 13 lines · Al Viro

[my apologies to the folks on Cc, original mails got the list address buggered in To:, thus the resend of the entire series just to the list]

Quoted 4 lines · Al Viro

... or it could be done simpler, if we keep the current logics for Int_const_expr flag at parse time and add a 'const expression' one with rules as above. Anyway, I'm going to get some sleep before dealing with that crap.

From: Al Viro <[email protected]>
Date: Sun, 1 Jul 2007 02:28:10 -0400
Subject: [PATCH] fix the comma handling in integer constant expressions

Quoted 5 lines

Treat it as normal binary operation, taint the value, check the taint. We can do other kind of value tainting with the same infrastructure as well...

Review and testing would be welcome; AFAICS, it works, but...

Seems to work for me. Applied.

I did notice one thing:

$ ./sparse /dev/stdin <<<"int x; struct { unsigned int i:x; };"
/dev/stdin:1:32: error: bad constant expression
/dev/stdin:1:33: error: invalid named zero-width bitfield `i'

That seems like double-warning for the same error. Probably a pain to suppress the second error, though.

- Josh Triplett