[PATCH 05/13] fix linearize_conditional() for logical ops

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The function linearize_conditional(), normaly used for conditionals
(c ? a : b) is also used to linearize the logical ops || and &&.
For conditionals, the type evaluation ensure that both LHS & RHS
have consistent types. However, this is not the case when used for
logical ops. This creates 2 separated but related problems:
* the operands are not compared with 0 as required by the standard
  (6.5.13, 6.5.14).
* both operands can have different, incompatible types and thus
  it's possible to have a phi-node with sources of different,
  incompatible types, which doesn't make sense.

Fix this by:
* add a flag to linearize_conditional() telling if it's used for
  a conditional or for a logical op.
* when used for logical ops:
  * first compare the operands againts zero
  * convert the boolean result to the expression's type.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 linearize.c                 | 17 +++++++++++++----
 validation/linear/logical.c |  1 -
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/linearize.c b/linearize.c
index 2b950210e..2b1b26582 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1615,7 +1615,8 @@ static pseudo_t linearize_short_conditional(struct entrypoint *ep, struct expres
 static pseudo_t linearize_conditional(struct entrypoint *ep, struct expression *expr,
 				      struct expression *cond,
 				      struct expression *expr_true,
-				      struct expression *expr_false)
+				      struct expression *expr_false,
+				      int logical)
 {
 	pseudo_t src1, src2;
 	pseudo_t phi1, phi2;
@@ -1631,11 +1632,19 @@ static pseudo_t linearize_conditional(struct entrypoint *ep, struct expression *
 
 	set_activeblock(ep, bb_true);
 	src1 = linearize_expression(ep, expr_true);
+	if (logical) {
+		src1 = add_convert_to_bool(ep, src1, expr_true->ctype);
+		src1 = cast_pseudo(ep, src1, &bool_ctype, expr->ctype);
+	}
 	phi1 = alloc_phi(ep->active, src1, expr->ctype);
 	add_goto(ep, merge); 
 
 	set_activeblock(ep, bb_false);
 	src2 = linearize_expression(ep, expr_false);
+	if (logical) {
+		src2 = add_convert_to_bool(ep, src2, expr_false->ctype);
+		src2 = cast_pseudo(ep, src2, &bool_ctype, expr->ctype);
+	}
 	phi2 = alloc_phi(ep->active, src2, expr->ctype);
 	set_activeblock(ep, merge);
 
@@ -1649,8 +1658,8 @@ static pseudo_t linearize_logical(struct entrypoint *ep, struct expression *expr
 	shortcut = alloc_const_expression(expr->pos, expr->op == SPECIAL_LOGICAL_OR);
 	shortcut->ctype = expr->ctype;
 	if (expr->op == SPECIAL_LOGICAL_OR)
-		return linearize_conditional(ep, expr, expr->left, shortcut, expr->right);
-	return linearize_conditional(ep, expr, expr->left, expr->right, shortcut);
+		return linearize_conditional(ep, expr, expr->left, shortcut, expr->right, 1);
+	return linearize_conditional(ep, expr, expr->left, expr->right, shortcut, 1);
 }
 
 static pseudo_t linearize_compare(struct entrypoint *ep, struct expression *expr)
@@ -1829,7 +1838,7 @@ static pseudo_t linearize_expression(struct entrypoint *ep, struct expression *e
 			return linearize_short_conditional(ep, expr, expr->conditional, expr->cond_false);
 
 		return  linearize_conditional(ep, expr, expr->conditional,
-					      expr->cond_true, expr->cond_false);
+					      expr->cond_true, expr->cond_false, 0);
 
 	case EXPR_COMMA:
 		linearize_expression(ep, expr->left);
diff --git a/validation/linear/logical.c b/validation/linear/logical.c
index 645adc565..972f87098 100644
--- a/validation/linear/logical.c
+++ b/validation/linear/logical.c
@@ -19,7 +19,6 @@ int ad(int i, struct S *b) { return i && b->d; }
 /*
  * check-name: logical
  * check-command: test-linearize -m64 -fdump-ir -Wno-decl $file
- * check-known-to-fail
  *
  * check-output-start
 os:
-- 
2.18.0

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux