utils2.c (known_alignment): Derive the alignment from pointed-to types only if it is otherwise unknown.
* utils2.c (known_alignment): Derive the alignment from pointed-to types only if it is otherwise unknown. <INTEGER_CST>: Tidy. <MULT_EXPR>: Likewise. <POINTER_PLUS_EXPR>: If the alignment of the offset is unknown, use that of the base. From-SVN: r137081
This commit is contained in:
parent
a057a4f13b
commit
324ed5a676
@ -1,3 +1,12 @@
|
||||
2008-06-24 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* utils2.c (known_alignment): Derive the alignment from pointed-to
|
||||
types only if it is otherwise unknown.
|
||||
<INTEGER_CST>: Tidy.
|
||||
<MULT_EXPR>: Likewise.
|
||||
<POINTER_PLUS_EXPR>: If the alignment of the offset is unknown, use
|
||||
that of the base.
|
||||
|
||||
2008-06-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
|
||||
|
||||
PR ada/36573
|
||||
|
@ -136,23 +136,6 @@ known_alignment (tree exp)
|
||||
{
|
||||
unsigned int this_alignment;
|
||||
unsigned int lhs, rhs;
|
||||
unsigned int type_alignment;
|
||||
|
||||
/* For pointer expressions, we know that the designated object is always at
|
||||
least as strictly aligned as the designated subtype, so we account for
|
||||
both type and expression information in this case.
|
||||
|
||||
Beware that we can still get a dummy designated subtype here (e.g. Taft
|
||||
Amendment types), in which the alignment information is meaningless and
|
||||
should be ignored.
|
||||
|
||||
We always compute a type_alignment value and return the MAX of it
|
||||
compared with what we get from the expression tree. Just set the
|
||||
type_alignment value to 0 when the type information is to be ignored. */
|
||||
type_alignment
|
||||
= ((POINTER_TYPE_P (TREE_TYPE (exp))
|
||||
&& !TYPE_IS_DUMMY_P (TREE_TYPE (TREE_TYPE (exp))))
|
||||
? TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))) : 0);
|
||||
|
||||
switch (TREE_CODE (exp))
|
||||
{
|
||||
@ -170,7 +153,6 @@ known_alignment (tree exp)
|
||||
break;
|
||||
|
||||
case PLUS_EXPR:
|
||||
case POINTER_PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
/* If two address are added, the alignment of the result is the
|
||||
minimum of the two alignments. */
|
||||
@ -179,6 +161,17 @@ known_alignment (tree exp)
|
||||
this_alignment = MIN (lhs, rhs);
|
||||
break;
|
||||
|
||||
case POINTER_PLUS_EXPR:
|
||||
lhs = known_alignment (TREE_OPERAND (exp, 0));
|
||||
rhs = known_alignment (TREE_OPERAND (exp, 1));
|
||||
/* If we don't know the alignment of the offset, we assume that
|
||||
of the base. */
|
||||
if (rhs == 0)
|
||||
this_alignment = lhs;
|
||||
else
|
||||
this_alignment = MIN (lhs, rhs);
|
||||
break;
|
||||
|
||||
case COND_EXPR:
|
||||
/* If there is a choice between two values, use the smallest one. */
|
||||
lhs = known_alignment (TREE_OPERAND (exp, 1));
|
||||
@ -187,12 +180,12 @@ known_alignment (tree exp)
|
||||
break;
|
||||
|
||||
case INTEGER_CST:
|
||||
{
|
||||
unsigned HOST_WIDE_INT c = TREE_INT_CST_LOW (exp);
|
||||
/* The first part of this represents the lowest bit in the constant,
|
||||
but is it in bytes, not bits. */
|
||||
this_alignment
|
||||
= MIN (BITS_PER_UNIT
|
||||
* (TREE_INT_CST_LOW (exp) & - TREE_INT_CST_LOW (exp)),
|
||||
BIGGEST_ALIGNMENT);
|
||||
but it is originally in bytes, not bits. */
|
||||
this_alignment = MIN (BITS_PER_UNIT * (c & -c), BIGGEST_ALIGNMENT);
|
||||
}
|
||||
break;
|
||||
|
||||
case MULT_EXPR:
|
||||
@ -201,10 +194,12 @@ known_alignment (tree exp)
|
||||
lhs = known_alignment (TREE_OPERAND (exp, 0));
|
||||
rhs = known_alignment (TREE_OPERAND (exp, 1));
|
||||
|
||||
if (lhs == 0 || rhs == 0)
|
||||
this_alignment = MIN (BIGGEST_ALIGNMENT, MAX (lhs, rhs));
|
||||
if (lhs == 0)
|
||||
this_alignment = rhs;
|
||||
else if (rhs == 0)
|
||||
this_alignment = lhs;
|
||||
else
|
||||
this_alignment = MIN (BIGGEST_ALIGNMENT, lhs * rhs);
|
||||
this_alignment = MIN (lhs * rhs, BIGGEST_ALIGNMENT);
|
||||
break;
|
||||
|
||||
case BIT_AND_EXPR:
|
||||
@ -220,11 +215,19 @@ known_alignment (tree exp)
|
||||
break;
|
||||
|
||||
default:
|
||||
/* For other pointer expressions, we assume that the pointed-to object
|
||||
is at least as aligned as the pointed-to type. Beware that we can
|
||||
have a dummy type here (e.g. a Taft Amendment type), for which the
|
||||
alignment is meaningless and should be ignored. */
|
||||
if (POINTER_TYPE_P (TREE_TYPE (exp))
|
||||
&& !TYPE_IS_DUMMY_P (TREE_TYPE (TREE_TYPE (exp))))
|
||||
this_alignment = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
|
||||
else
|
||||
this_alignment = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return MAX (type_alignment, this_alignment);
|
||||
return this_alignment;
|
||||
}
|
||||
|
||||
/* We have a comparison or assignment operation on two types, T1 and T2, which
|
||||
|
@ -1,3 +1,7 @@
|
||||
2008-06-24 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gnat.dg/warn5.adb: New test.
|
||||
|
||||
2008-06-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/36504
|
||||
|
34
gcc/testsuite/gnat.dg/warn5.adb
Normal file
34
gcc/testsuite/gnat.dg/warn5.adb
Normal file
@ -0,0 +1,34 @@
|
||||
-- { dg-do compile }
|
||||
|
||||
with System;
|
||||
with Unchecked_Conversion;
|
||||
|
||||
procedure Warn5 is
|
||||
|
||||
type Digit_Type is range 0..15;
|
||||
|
||||
type Frequency_Type is array( 1..12) of Digit_Type;
|
||||
pragma Pack(Frequency_Type);
|
||||
|
||||
type Element_Type is record
|
||||
F : Frequency_Type;
|
||||
end record;
|
||||
|
||||
type Array_Type is array (Natural range <>) of Element_Type;
|
||||
|
||||
type List_Type is record
|
||||
A : Array_Type (0..1);
|
||||
end record;
|
||||
for List_Type'Alignment use 4;
|
||||
|
||||
type Pointer_Type is access Element_Type;
|
||||
function To_Ptr is new Unchecked_Conversion(System.Address, Pointer_Type);
|
||||
|
||||
function Pointer (Pos : Natural; List : List_Type) return Pointer_Type is
|
||||
begin
|
||||
return To_Ptr(List.A(Pos)'Address); -- { dg-warning "source alignment" "" { target alpha*-*-* hppa*-*-* ia64-*-* mips*-*-* sparc*-*-* } }
|
||||
end;
|
||||
|
||||
begin
|
||||
null;
|
||||
end;
|
Loading…
Reference in New Issue
Block a user