diff options
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 56 |
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; } |