diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2008-06-24 18:15:36 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2008-06-24 18:15:36 +0000 |
commit | 324ed5a676f020e3bd4b37f40028025d1e915bbf (patch) | |
tree | 1f4c859fa21f77b99e36f9bd2885a7fe48b8f631 | |
parent | a057a4f13b2599c7fa19bf08b9617b6b3f67d2d7 (diff) | |
download | gcc-324ed5a676f020e3bd4b37f40028025d1e915bbf.zip gcc-324ed5a676f020e3bd4b37f40028025d1e915bbf.tar.gz gcc-324ed5a676f020e3bd4b37f40028025d1e915bbf.tar.bz2 |
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
-rw-r--r-- | gcc/ada/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/ada/utils2.c | 61 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/warn5.adb | 34 |
4 files changed, 79 insertions, 29 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 74728b2..be34816 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -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 diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c index 891463c..300fbd3 100644 --- a/gcc/ada/utils2.c +++ b/gcc/ada/utils2.c @@ -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: - /* 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); + { + unsigned HOST_WIDE_INT c = TREE_INT_CST_LOW (exp); + /* The first part of this represents the lowest bit in the constant, + 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: - this_alignment = 0; + /* 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c7a7cd2..4c569c2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/gnat.dg/warn5.adb b/gcc/testsuite/gnat.dg/warn5.adb new file mode 100644 index 0000000..108bc59 --- /dev/null +++ b/gcc/testsuite/gnat.dg/warn5.adb @@ -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; |