linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC 11/13] evaluate: relax some constant expression rules for pointer expressions
@ 2015-07-22 23:23 Nicolai Stange
  0 siblings, 0 replies; only message in thread
From: Nicolai Stange @ 2015-07-22 23:23 UTC (permalink / raw)
  To: linux-sparse

The official constraints on constant expressions [6.6] are insanely
strict in that they do not allow some constructs commonly used in the
wild.

Relax them by treating
- address constants cast to different pointer type as address constants
  again,
- address constants cast to integer type as integer constant
  expressions
- conditional expressions whose true and false branches both yield
  address constants as address constants,
- and conditional expressions whose condition is an address constant
  as an constant expression to the extent their true and false branches
  allow.

Signed-off-by: Nicolai Stange <nicstange@gmail.com>
---
 evaluate.c | 37 ++++++++++++++++++++++++++++++++-----
 1 file changed, 32 insertions(+), 5 deletions(-)

diff --git a/evaluate.c b/evaluate.c
index c115e64..ee5f18f 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1125,14 +1125,25 @@ static struct symbol *evaluate_conditional_expression(struct expression *expr)
 		true = &expr->cond_true;
 	}
 
-	expr->flags |= expr_flags_decay_consts(expr->conditional->flags &
-					(*true)->flags &
-					expr->cond_false->flags);
 	/*
+	 * A conditional operator yields a particular constant
+	 * expression type only if all of its three subexpressions are
+	 * of that type [6.6(6), 6.6(8)].
+	 * As an extension, relax this restriction by allowing any
+	 * constant expression type for the condition expression.
+	 *
 	 * A conditional operator never yields an address constant
 	 * [6.6(9)].
+	 * However, as an extension, if the condition is any constant
+	 * expression, and the true and false expressions are both
+	 * address constants, mark the result as an address constant.
 	 */
-	expr->flags &= ~expr_clear_flag_mask(EXPR_FLAG_ADDR_CONST_EXPR);
+	if ((expr->conditional->flags &
+			(expr_set_flag_mask(EXPR_FLAG_ARITH_CONST_EXPR) |
+				expr_set_flag_mask(EXPR_FLAG_ADDR_CONST_EXPR))))
+		expr->flags |=
+			expr_flags_decay_consts((*true)->flags &
+						expr->cond_false->flags);
 
 	lclass = classify_type(ltype, &ltype);
 	rclass = classify_type(rtype, &rtype);
@@ -2780,15 +2791,31 @@ static struct symbol *evaluate_cast(struct expression *expr)
 		/*
 		 * Casts of integer literals to pointer type yield
 		 * address constants [6.6(9)].
+		 *
+		 * As an extension, treat address constants cast to a
+		 * different pointer type as address constants again.
+		 *
+		 * As another extension, treat integer constant
+		 * expressions (in contrast to literals) cast to
+		 * pointer type as address constants.
 		 */
 		if (class1 & TYPE_PTR &&
-			(target->flags & EXPR_FLAG_INT_CONST)) {
+			((target->flags & EXPR_FLAG_INT_CONST_EXPR) ||
+				(target->flags & EXPR_FLAG_ADDR_CONST_EXPR))) {
 			expr->flags |=
 				expr_set_flag_mask(EXPR_FLAG_ADDR_CONST_EXPR);
 
 		}
 	} else {
 		expr->flags |= expr_flags_decay_consts(target->flags);
+
+		/*
+		 * As an extension, treat address constants cast to
+		 * integer type as an arithmetic constant.
+		 */
+		if (expr->flags & EXPR_FLAG_ADDR_CONST_EXPR)
+			expr->flags |=
+				expr_set_flag_mask(EXPR_FLAG_ARITH_CONST_EXPR);
 		/*
 		 * Casts to numeric types never result in address
 		 * constants [6.6(9)].
-- 
2.4.5


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2015-07-22 23:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-22 23:23 [PATCH RFC 11/13] evaluate: relax some constant expression rules for pointer expressions Nicolai Stange

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