From 324ed5a676f020e3bd4b37f40028025d1e915bbf Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 24 Jun 2008 18:15:36 +0000 Subject: [PATCH] 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. : Tidy. : Likewise. : If the alignment of the offset is unknown, use that of the base. From-SVN: r137081 --- gcc/ada/ChangeLog | 9 +++++ gcc/ada/utils2.c | 61 +++++++++++++++++---------------- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gnat.dg/warn5.adb | 34 ++++++++++++++++++ 4 files changed, 79 insertions(+), 29 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/warn5.adb diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 74728b2ae3e..be34816b3f4 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,12 @@ +2008-06-24 Eric Botcazou + + * utils2.c (known_alignment): Derive the alignment from pointed-to + types only if it is otherwise unknown. + : Tidy. + : Likewise. + : If the alignment of the offset is unknown, use + that of the base. + 2008-06-20 John David Anglin PR ada/36573 diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c index 891463ce49c..300fbd37d01 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 c7a7cd26fb4..4c569c26edb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-06-24 Eric Botcazou + + * gnat.dg/warn5.adb: New test. + 2008-06-24 Jakub Jelinek 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 00000000000..108bc594c0c --- /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;