aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c56
1 files changed, 29 insertions, 27 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index a5205ce..094d7e0 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -1337,7 +1337,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
}
if (TREE_CODE (TYPE_SIZE_UNIT (gnu_alloc_type)) == INTEGER_CST
- && TREE_OVERFLOW (TYPE_SIZE_UNIT (gnu_alloc_type)))
+ && !valid_constant_size_p (TYPE_SIZE_UNIT (gnu_alloc_type)))
post_error ("?`Storage_Error` will be raised at run time!",
gnat_entity);
@@ -4240,8 +4240,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
a function that returns that type. This usage doesn't make
sense anyway, so give an error here. */
if (TYPE_SIZE_UNIT (gnu_return_type)
- && TREE_CONSTANT (TYPE_SIZE_UNIT (gnu_return_type))
- && TREE_OVERFLOW (TYPE_SIZE_UNIT (gnu_return_type)))
+ && TREE_CODE (TYPE_SIZE_UNIT (gnu_return_type)) == INTEGER_CST
+ && !valid_constant_size_p (TYPE_SIZE_UNIT (gnu_return_type)))
{
post_error ("cannot return type whose size overflows",
gnat_entity);
@@ -5989,10 +5989,9 @@ elaborate_entity (Entity_Id gnat_entity)
static bool
allocatable_size_p (tree gnu_size, bool static_p)
{
- /* We can allocate a fixed size if it hasn't overflowed and can be handled
- (efficiently) on the host. */
+ /* We can allocate a fixed size if it is a valid for the middle-end. */
if (TREE_CODE (gnu_size) == INTEGER_CST)
- return !TREE_OVERFLOW (gnu_size) && host_integerp (gnu_size, 1);
+ return valid_constant_size_p (gnu_size);
/* We can allocate a variable size if this isn't a static allocation. */
else
@@ -7254,7 +7253,7 @@ static Uint
annotate_value (tree gnu_size)
{
TCode tcode;
- Node_Ref_Or_Val ops[3], ret;
+ Node_Ref_Or_Val ops[3], ret, pre_op1 = No_Uint;
struct tree_int_map in;
int i;
@@ -7283,24 +7282,7 @@ annotate_value (tree gnu_size)
switch (TREE_CODE (gnu_size))
{
case INTEGER_CST:
- if (TREE_OVERFLOW (gnu_size))
- return No_Uint;
-
- /* This may come from a conversion from some smaller type, so ensure
- this is in bitsizetype. */
- gnu_size = convert (bitsizetype, gnu_size);
-
- /* For a negative value, build NEGATE_EXPR of the opposite. Such values
- appear in expressions containing aligning patterns. Note that, since
- sizetype is sign-extended but nonetheless unsigned, we don't directly
- use tree_int_cst_sgn. */
- if (TREE_INT_CST_HIGH (gnu_size) < 0)
- {
- tree op_size = fold_build1 (NEGATE_EXPR, bitsizetype, gnu_size);
- return annotate_value (build1 (NEGATE_EXPR, bitsizetype, op_size));
- }
-
- return UI_From_gnu (gnu_size);
+ return TREE_OVERFLOW (gnu_size) ? No_Uint : UI_From_gnu (gnu_size);
case COMPONENT_REF:
/* The only case we handle here is a simple discriminant reference. */
@@ -7339,7 +7321,6 @@ annotate_value (tree gnu_size)
case TRUTH_OR_EXPR: tcode = Truth_Or_Expr; break;
case TRUTH_XOR_EXPR: tcode = Truth_Xor_Expr; break;
case TRUTH_NOT_EXPR: tcode = Truth_Not_Expr; break;
- case BIT_AND_EXPR: tcode = Bit_And_Expr; break;
case LT_EXPR: tcode = Lt_Expr; break;
case LE_EXPR: tcode = Le_Expr; break;
case GT_EXPR: tcode = Gt_Expr; break;
@@ -7347,6 +7328,24 @@ annotate_value (tree gnu_size)
case EQ_EXPR: tcode = Eq_Expr; break;
case NE_EXPR: tcode = Ne_Expr; break;
+ case BIT_AND_EXPR:
+ tcode = Bit_And_Expr;
+ /* For negative values, build NEGATE_EXPR of the opposite. Such values
+ appear in expressions containing aligning patterns. Note that, since
+ sizetype is unsigned, we have to jump through some hoops. */
+ if (TREE_CODE (TREE_OPERAND (gnu_size, 1)) == INTEGER_CST)
+ {
+ tree op1 = TREE_OPERAND (gnu_size, 1);
+ double_int signed_op1
+ = tree_to_double_int (op1).sext (TYPE_PRECISION (sizetype));
+ if (signed_op1.is_negative ())
+ {
+ op1 = double_int_to_tree (sizetype, -signed_op1);
+ pre_op1 = annotate_value (build1 (NEGATE_EXPR, sizetype, op1));
+ }
+ }
+ break;
+
case CALL_EXPR:
{
tree t = maybe_inline_call_in_expr (gnu_size);
@@ -7367,7 +7366,10 @@ annotate_value (tree gnu_size)
for (i = 0; i < TREE_CODE_LENGTH (TREE_CODE (gnu_size)); i++)
{
- ops[i] = annotate_value (TREE_OPERAND (gnu_size, i));
+ if (i == 1 && pre_op1 != No_Uint)
+ ops[i] = pre_op1;
+ else
+ ops[i] = annotate_value (TREE_OPERAND (gnu_size, i));
if (ops[i] == No_Uint)
return No_Uint;
}