diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2012-11-28 10:51:19 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2012-11-28 10:51:19 +0000 |
commit | ce3da0d0d54ce3e469828698ba1ac5f25146b6f9 (patch) | |
tree | 66a07373943672c9d9ef3f8e395acb3f21fe89cd /gcc/ada/gcc-interface/decl.c | |
parent | fb1fbef2735bce7c62511daf6f64343d9d97e299 (diff) | |
download | gcc-ce3da0d0d54ce3e469828698ba1ac5f25146b6f9.zip gcc-ce3da0d0d54ce3e469828698ba1ac5f25146b6f9.tar.gz gcc-ce3da0d0d54ce3e469828698ba1ac5f25146b6f9.tar.bz2 |
stor-layout.c (layout_type): Do not clear TREE_OVERFLOW on overflowed zeroes, except in one specific case.
* stor-layout.c (layout_type) <ARRAY_TYPE>: Do not clear TREE_OVERFLOW
on overflowed zeroes, except in one specific case.
ada/
* gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Use
valid_constant_size_p to detect too large objects.
<E_Subprogram_Type>: Likewise for too large return types.
(allocatable_size_p): Call valid_constant_size_p in the fixed case.
(annotate_value) <INTEGER_CST>: Simplify.
<BIT_AND_EXPR>: Deal with negative values here.
* gcc-interface/trans.c (gnat_to_gnu) <N_Assignment_Statement>: Use
valid_constant_size_p to detect too large objects on the LHS.
* gcc-interface/misc.c (default_pass_by_ref): Likewise for large types.
And use TYPE_SIZE_UNIT throughout.
(must_pass_by_ref): Likewise.
* gcc-interface/utils.c (max_size) <tcc_unary>: Split from common case.
<tcc_binary>: Likewise. Call size_binop instead of fold_build2.
<tcc_expression>: Simplify.
* gcc-interface/utils2.c (build_allocator): Use valid_constant_size_p
to detect too large allocations.
From-SVN: r193886
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; } |