This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Ada] Fix PR ada/24880 and PR ada/26635
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 13 May 2008 10:49:01 +0200
- Subject: [Ada] Fix PR ada/24880 and PR ada/26635
PR ada/26635 is a bogus Storage_Error warning introduced by the fix for PR
tree-optimization/25125. I initially complained about this fix but I now
think that the problem can be interpreted slightly differently: the conversion
introduced by the fix is correct under the assumption that the arithmetics
doesn't trap on overflow resulting from conversions from unsigned to signed,
which is true on the hardware since such conversions are no-op. The problem
arises with the arithmetics of the compiler performed on PLACEHOLDER_EXPRs,
because of the propagation of TREE_OVERFLOW during the substitution, so I
think it's reasonable to make a special case here.
All the more so that another special case needs to be made at the same place
for biased types to avoid an endless loop because of the same conversion, this
is PR ada/24880.
Tested on i586-suse-linux, applied on the mainline and 4.3 branch.
2008-05-13 Eric Botcazou <ebotcazou@adacore.com>
PR ada/24880
PR ada/26635
* utils.c (convert) <INTEGER_TYPE>: When converting an additive
expression to an integral type with lower precision, use NOP_EXPR
directly in a couple of special cases.
2008-05-13 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/discr7.adb: New test.
* gnat.dg/conv_integer.adb: Likewise.
--
Eric Botcazou
Index: utils.c
===================================================================
--- utils.c (revision 135221)
+++ utils.c (working copy)
@@ -3627,7 +3627,7 @@ convert (tree type, tree expr)
if (TYPE_FAT_POINTER_P (type) && !TYPE_FAT_POINTER_P (etype))
return convert_to_fat_pointer (type, expr);
- /* If we're converting between two aggregate types that are mere
+ /* If we are converting between two aggregate types that are mere
variants, just make a VIEW_CONVERT_EXPR. */
else if (code == ecode
&& AGGREGATE_TYPE_P (type)
@@ -3662,6 +3662,30 @@ convert (tree type, tree expr)
/* ... fall through ... */
case ENUMERAL_TYPE:
+ /* If we are converting an additive expression to an integer type
+ with lower precision, be wary of the optimization that can be
+ applied by convert_to_integer. There are 2 problematic cases:
+ - if the first operand was originally of a biased type,
+ because we could be recursively called to convert it
+ to an intermediate type and thus rematerialize the
+ additive operator endlessly,
+ - if the expression contains a placeholder, because an
+ intermediate conversion that changes the sign could
+ be inserted and thus introduce an artificial overflow
+ at compile time when the placeholder is substituted. */
+ if (code == INTEGER_TYPE
+ && ecode == INTEGER_TYPE
+ && TYPE_PRECISION (type) < TYPE_PRECISION (etype)
+ && (TREE_CODE (expr) == PLUS_EXPR || TREE_CODE (expr) == MINUS_EXPR))
+ {
+ tree op0 = get_unwidened (TREE_OPERAND (expr, 0), type);
+
+ if ((TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
+ && TYPE_BIASED_REPRESENTATION_P (TREE_TYPE (op0)))
+ || CONTAINS_PLACEHOLDER_P (expr))
+ return build1 (NOP_EXPR, type, expr);
+ }
+
return fold (convert_to_integer (type, expr));
case POINTER_TYPE:
-- { dg-do compile }
procedure Discr7 is
subtype Index is Natural range 0..5;
type BitString is array(Index range <>) of Boolean;
pragma Pack(BitString);
function Id (I : Integer) return Integer is
begin
return I;
end;
type E(D : Index) is record
C : BitString(1..D);
end record;
subtype E0 is E(Id(0));
function F return E0 is
begin
return E'(D=>0, C=>(1..0=>FALSE));
end;
begin
null;
end;
-- { dg-do compile }
-- { dg-options "-gnatws" }
procedure Conv_Integer is
S : constant := Integer'Size;
type Regoff_T is range -1 .. 2 ** (S-1);
for Regoff_T'Size use S;
B : Integer;
C : Regoff_T;
begin
B := Integer (C);
end;