Commit 881cdd61 by Eric Botcazou Committed by Eric Botcazou

trans.c (Attribute_to_gnu): If the type is a floating-point type...

	* gcc-interface/trans.c (Attribute_to_gnu) <Attr_{Min,Max}>: If the
	type is a floating-point type, implement the semantics of the C99
	f{min,max} routines with regard to NaNs.
	(gnat_to_gnu): Call builtin_decl_implicit.
	* gcc-interface/utils2.c (compare_arrays): Adjust comments.

From-SVN: r219010
parent 35786aad
2014-12-22 Eric Botcazou <ebotcazou@adacore.com> 2014-12-22 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (Attribute_to_gnu) <Attr_{Min,Max}>: If the
type is a floating-point type, implement the semantics of the C99
f{min,max} routines with regard to NaNs.
(gnat_to_gnu): Call builtin_decl_implicit.
* gcc-interface/utils2.c (compare_arrays): Adjust comments.
2014-12-22 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_field): Post the error message * gcc-interface/decl.c (gnat_to_gnu_field): Post the error message
for parent overlapping on the position instead of on the first bit. for parent overlapping on the position instead of on the first bit.
For a field that needs strict alignment, issue the error for the For a field that needs strict alignment, issue the error for the
......
...@@ -2268,9 +2268,56 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) ...@@ -2268,9 +2268,56 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
tree gnu_rhs = gnat_to_gnu (Next (First (Expressions (gnat_node)))); tree gnu_rhs = gnat_to_gnu (Next (First (Expressions (gnat_node))));
gnu_result_type = get_unpadded_type (Etype (gnat_node)); gnu_result_type = get_unpadded_type (Etype (gnat_node));
gnu_result = build_binary_op (attribute == Attr_Min
? MIN_EXPR : MAX_EXPR, /* The result of {MIN,MAX}_EXPR is unspecified if either operand is
gnu_result_type, gnu_lhs, gnu_rhs); a NaN so we implement the semantics of C99 f{min,max} to make it
predictable in this case: if either operand is a NaN, the other
is returned; if both operands are NaN's, a NaN is returned. */
if (SCALAR_FLOAT_TYPE_P (gnu_result_type))
{
const bool lhs_side_effects_p = TREE_SIDE_EFFECTS (gnu_lhs);
const bool rhs_side_effects_p = TREE_SIDE_EFFECTS (gnu_rhs);
tree t = builtin_decl_explicit (BUILT_IN_ISNAN);
tree lhs_is_nan, rhs_is_nan;
/* If the operands have side-effects, they need to be evaluated
only once in spite of the multiple references in the result. */
if (lhs_side_effects_p)
gnu_lhs = gnat_protect_expr (gnu_lhs);
if (rhs_side_effects_p)
gnu_rhs = gnat_protect_expr (gnu_rhs);
lhs_is_nan = fold_build2 (NE_EXPR, boolean_type_node,
build_call_expr (t, 1, gnu_lhs),
integer_zero_node);
rhs_is_nan = fold_build2 (NE_EXPR, boolean_type_node,
build_call_expr (t, 1, gnu_rhs),
integer_zero_node);
gnu_result = build_binary_op (attribute == Attr_Min
? MIN_EXPR : MAX_EXPR,
gnu_result_type, gnu_lhs, gnu_rhs);
gnu_result = fold_build3 (COND_EXPR, gnu_result_type,
rhs_is_nan, gnu_lhs, gnu_result);
gnu_result = fold_build3 (COND_EXPR, gnu_result_type,
lhs_is_nan, gnu_rhs, gnu_result);
/* If the operands have side-effects, they need to be evaluated
before doing the tests above since the place they otherwise
would end up being evaluated at run time could be wrong. */
if (lhs_side_effects_p)
gnu_result
= build2 (COMPOUND_EXPR, gnu_result_type, gnu_lhs, gnu_result);
if (rhs_side_effects_p)
gnu_result
= build2 (COMPOUND_EXPR, gnu_result_type, gnu_rhs, gnu_result);
}
else
gnu_result = build_binary_op (attribute == Attr_Min
? MIN_EXPR : MAX_EXPR,
gnu_result_type, gnu_lhs, gnu_rhs);
} }
break; break;
...@@ -6458,7 +6505,7 @@ gnat_to_gnu (Node_Id gnat_node) ...@@ -6458,7 +6505,7 @@ gnat_to_gnu (Node_Id gnat_node)
tree size tree size
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (type), to); = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (type), to);
tree to_ptr = build_fold_addr_expr (to); tree to_ptr = build_fold_addr_expr (to);
tree t = builtin_decl_implicit (BUILT_IN_MEMSET); tree t = builtin_decl_explicit (BUILT_IN_MEMSET);
if (TREE_CODE (value) == INTEGER_CST) if (TREE_CODE (value) == INTEGER_CST)
{ {
tree mask tree mask
...@@ -6488,7 +6535,7 @@ gnat_to_gnu (Node_Id gnat_node) ...@@ -6488,7 +6535,7 @@ gnat_to_gnu (Node_Id gnat_node)
= SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (type), from); = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (type), from);
tree to_ptr = build_fold_addr_expr (to); tree to_ptr = build_fold_addr_expr (to);
tree from_ptr = build_fold_addr_expr (from); tree from_ptr = build_fold_addr_expr (from);
tree t = builtin_decl_implicit (BUILT_IN_MEMMOVE); tree t = builtin_decl_explicit (BUILT_IN_MEMMOVE);
gnu_result = build_call_expr (t, 3, to_ptr, from_ptr, size); gnu_result = build_call_expr (t, 3, to_ptr, from_ptr, size);
} }
} }
......
...@@ -255,8 +255,8 @@ compare_arrays (location_t loc, tree result_type, tree a1, tree a2) ...@@ -255,8 +255,8 @@ compare_arrays (location_t loc, tree result_type, tree a1, tree a2)
bool a2_side_effects_p = TREE_SIDE_EFFECTS (a2); bool a2_side_effects_p = TREE_SIDE_EFFECTS (a2);
bool length_zero_p = false; bool length_zero_p = false;
/* If either operand has side-effects, they have to be evaluated only once /* If the operands have side-effects, they need to be evaluated only once
in spite of the multiple references to the operand in the comparison. */ in spite of the multiple references in the comparison. */
if (a1_side_effects_p) if (a1_side_effects_p)
a1 = gnat_protect_expr (a1); a1 = gnat_protect_expr (a1);
...@@ -419,9 +419,9 @@ compare_arrays (location_t loc, tree result_type, tree a1, tree a2) ...@@ -419,9 +419,9 @@ compare_arrays (location_t loc, tree result_type, tree a1, tree a2)
a1_is_null, a2_is_null), a1_is_null, a2_is_null),
result); result);
/* If either operand has side-effects, they have to be evaluated before /* If the operands have side-effects, they need to be evaluated before
starting the comparison above since the place they would be otherwise doing the tests above since the place they otherwise would end up
evaluated could be wrong. */ being evaluated at run time could be wrong. */
if (a1_side_effects_p) if (a1_side_effects_p)
result = build2 (COMPOUND_EXPR, result_type, a1, result); result = build2 (COMPOUND_EXPR, result_type, a1, result);
......
2014-12-22 Eric Botcazou <ebotcazou@adacore.com> 2014-12-22 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/nan_max.adb: New test.
2014-12-22 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/volatile1.ads: New test. * gnat.dg/specs/volatile1.ads: New test.
* gnat.dg/specs/clause_on_volatile.ads: Adjust. * gnat.dg/specs/clause_on_volatile.ads: Adjust.
* gnat.dg/specs/size_clause3.ads: Likewise. * gnat.dg/specs/size_clause3.ads: Likewise.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment