While testing some other issues with C++'s __java_boolean type
occurred. So I adjusted check in test-cfg.c as you suggested.
Additionally due the fact that we are now boolifying conditions for
even BOOLEAN_TYPE'ed cases (for making sure inner arms are boolified,
too), we possibly would alter here truth-type provided by FE. To
restore original type (for types != boolean-type), we do type
conversion always back to FE's used type for truth-AND/OR/XOR/etc as
result.
Patch bootstrapped with all languages on x86_64-pc-linux-gnu
(multilib). Ok for apply?
Regards,
Kai
Index: gcc/gcc/gimplify.c
===================================================================
--- gcc.orig/gcc/gimplify.c 2011-05-12 09:02:58.946243000 +0200
+++ gcc/gcc/gimplify.c 2011-05-12 15:13:59.534550700 +0200
@@ -2824,9 +2824,6 @@ gimple_boolify (tree expr)
}
}
- if (TREE_CODE (type) == BOOLEAN_TYPE)
- return expr;
-
switch (TREE_CODE (expr))
{
case TRUTH_AND_EXPR:
@@ -2851,6 +2848,9 @@ gimple_boolify (tree expr)
default:
/* Other expressions that get here must have boolean values, but
might need to be converted to the appropriate mode. */
+ if (TREE_CODE (type) == BOOLEAN_TYPE
+ && type == boolean_type_node)
+ return expr;
return fold_convert_loc (loc, boolean_type_node, expr);
}
}
@@ -4695,31 +4695,6 @@ gimplify_scalar_mode_aggregate_compare (
return GS_OK;
}
-/* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions. EXPR_P
- points to the expression to gimplify.
-
- Expressions of the form 'a && b' are gimplified to:
-
- a && b ? true : false
-
- LOCUS is the source location to be put on the generated COND_EXPR.
- gimplify_cond_expr will do the rest. */
-
-static enum gimplify_status
-gimplify_boolean_expr (tree *expr_p, location_t locus)
-{
- /* Preserve the original type of the expression. */
- tree type = TREE_TYPE (*expr_p);
-
- *expr_p = build3 (COND_EXPR, type, *expr_p,
- fold_convert_loc (locus, type, boolean_true_node),
- fold_convert_loc (locus, type, boolean_false_node));
-
- SET_EXPR_LOCATION (*expr_p, locus);
-
- return GS_OK;
-}
-
/* Gimplify an expression sequence. This function gimplifies each
expression and rewrites the original expression with the last
expression of the sequence in GIMPLE form.
@@ -6762,12 +6737,26 @@ gimplify_expr (tree *expr_p, gimple_seq
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
- /* Pass the source location of the outer expression. */
- ret = gimplify_boolean_expr (expr_p, saved_location);
- break;
+ {
+ /* Preserve the original type of the expression and the
+ source location of the outer expression. */
+ tree org_type = TREE_TYPE (*expr_p);
+ *expr_p = gimple_boolify (*expr_p);
+ *expr_p = build3_loc (saved_location, COND_EXPR,
+ org_type, *expr_p,
+ fold_convert_loc
+ (saved_location,
+ org_type, boolean_true_node),
+ fold_convert_loc
+ (saved_location,
+ org_type, boolean_false_node));
+ ret = GS_OK;
+ break;
+ }
case TRUTH_NOT_EXPR:
- if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
+ if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE
+ || TREE_CODE (TREE_TYPE (*expr_p)) != boolean_type_node)
{
tree type = TREE_TYPE (*expr_p);
*expr_p = fold_convert (type, gimple_boolify (*expr_p));
@@ -7203,6 +7192,24 @@ gimplify_expr (tree *expr_p, gimple_seq
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
+ {
+ tree org_type = TREE_TYPE (*expr_p);
+
+ *expr_p = gimple_boolify (*expr_p);
+
+ /* This shouldn't happen, but due fold-const (and here especially
+ fold_truth_not_expr) happily uses operand type and doesn't
+ automatically uses boolean_type as result, we need to keep
+ orignal type. */
+ if (TREE_CODE (org_type) != BOOLEAN_TYPE
+ || TREE_CODE (TREE_TYPE (org_type)) != boolean_type_node)
+ {
+ *expr_p = fold_convert (org_type, *expr_p);
+ ret = GS_OK;
+ break;
+ }
+ }
+
/* Classified as tcc_expression. */
goto expr_2;
Index: gcc/gcc/tree-cfg.c
===================================================================
--- gcc.orig/gcc/tree-cfg.c 2011-05-12 09:02:58.989243000 +0200
+++ gcc/gcc/tree-cfg.c 2011-05-12 14:50:19.656249100 +0200
@@ -3541,10 +3541,10 @@ do_pointer_plus_expr_check:
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
{
- /* We allow any kind of integral typed argument and result. */
- if (!INTEGRAL_TYPE_P (rhs1_type)
- || !INTEGRAL_TYPE_P (rhs2_type)
- || !INTEGRAL_TYPE_P (lhs_type))
+ /* We allow only boolean typed or compatible argument and result. */
+ if (!useless_type_conversion_p (boolean_type_node, rhs1_type)
+ || !useless_type_conversion_p (boolean_type_node, rhs2_type)
+ || !useless_type_conversion_p (boolean_type_node, lhs_type))
{
error ("type mismatch in binary truth expression");
debug_generic_expr (lhs_type);
Index: gcc/gcc/gimplify.c
===================================================================
--- gcc.orig/gcc/gimplify.c 2011-05-12 09:02:58.946243000 +0200
+++ gcc/gcc/gimplify.c 2011-05-12 15:13:59.534550700 +0200
@@ -2824,9 +2824,6 @@ gimple_boolify (tree expr)
}
}
- if (TREE_CODE (type) == BOOLEAN_TYPE)
- return expr;
-
switch (TREE_CODE (expr))
{
case TRUTH_AND_EXPR:
@@ -2851,6 +2848,9 @@ gimple_boolify (tree expr)
default:
/* Other expressions that get here must have boolean values, but
might need to be converted to the appropriate mode. */
+ if (TREE_CODE (type) == BOOLEAN_TYPE
+ && type == boolean_type_node)
+ return expr;
return fold_convert_loc (loc, boolean_type_node, expr);
}
}
@@ -4695,31 +4695,6 @@ gimplify_scalar_mode_aggregate_compare (
return GS_OK;
}
-/* Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions. EXPR_P
- points to the expression to gimplify.
-
- Expressions of the form 'a && b' are gimplified to:
-
- a && b ? true : false
-
- LOCUS is the source location to be put on the generated COND_EXPR.
- gimplify_cond_expr will do the rest. */
-
-static enum gimplify_status
-gimplify_boolean_expr (tree *expr_p, location_t locus)
-{
- /* Preserve the original type of the expression. */
- tree type = TREE_TYPE (*expr_p);
-
- *expr_p = build3 (COND_EXPR, type, *expr_p,
- fold_convert_loc (locus, type, boolean_true_node),
- fold_convert_loc (locus, type, boolean_false_node));
-
- SET_EXPR_LOCATION (*expr_p, locus);
-
- return GS_OK;
-}
-
/* Gimplify an expression sequence. This function gimplifies each
expression and rewrites the original expression with the last
expression of the sequence in GIMPLE form.
@@ -6762,12 +6737,26 @@ gimplify_expr (tree *expr_p, gimple_seq
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
- /* Pass the source location of the outer expression. */
- ret = gimplify_boolean_expr (expr_p, saved_location);
- break;
+ {
+ /* Preserve the original type of the expression and the
+ source location of the outer expression. */
+ tree org_type = TREE_TYPE (*expr_p);
+ *expr_p = gimple_boolify (*expr_p);
+ *expr_p = build3_loc (saved_location, COND_EXPR,
+ org_type, *expr_p,
+ fold_convert_loc
+ (saved_location,
+ org_type, boolean_true_node),
+ fold_convert_loc
+ (saved_location,
+ org_type, boolean_false_node));
+ ret = GS_OK;
+ break;
+ }
case TRUTH_NOT_EXPR:
- if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE)
+ if (TREE_CODE (TREE_TYPE (*expr_p)) != BOOLEAN_TYPE
+ || TREE_CODE (TREE_TYPE (*expr_p)) != boolean_type_node)
{
tree type = TREE_TYPE (*expr_p);
*expr_p = fold_convert (type, gimple_boolify (*expr_p));
@@ -7203,6 +7192,24 @@ gimplify_expr (tree *expr_p, gimple_seq
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
+ {
+ tree org_type = TREE_TYPE (*expr_p);
+
+ *expr_p = gimple_boolify (*expr_p);
+
+ /* This shouldn't happen, but due fold-const (and here especially
+ fold_truth_not_expr) happily uses operand type and doesn't
+ automatically uses boolean_type as result, we need to keep
+ orignal type. */
+ if (TREE_CODE (org_type) != BOOLEAN_TYPE
+ || TREE_CODE (TREE_TYPE (org_type)) != boolean_type_node)
+ {
+ *expr_p = fold_convert (org_type, *expr_p);
+ ret = GS_OK;
+ break;
+ }
+ }
+
/* Classified as tcc_expression. */
goto expr_2;
Index: gcc/gcc/tree-cfg.c
===================================================================
--- gcc.orig/gcc/tree-cfg.c 2011-05-12 09:02:58.989243000 +0200
+++ gcc/gcc/tree-cfg.c 2011-05-12 14:50:19.656249100 +0200
@@ -3541,10 +3541,10 @@ do_pointer_plus_expr_check:
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
{
- /* We allow any kind of integral typed argument and result. */
- if (!INTEGRAL_TYPE_P (rhs1_type)
- || !INTEGRAL_TYPE_P (rhs2_type)
- || !INTEGRAL_TYPE_P (lhs_type))
+ /* We allow only boolean typed or compatible argument and result. */
+ if (!useless_type_conversion_p (boolean_type_node, rhs1_type)
+ || !useless_type_conversion_p (boolean_type_node, rhs2_type)
+ || !useless_type_conversion_p (boolean_type_node, lhs_type))
{
error ("type mismatch in binary truth expression");
debug_generic_expr (lhs_type);