aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2008-06-24 18:15:36 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2008-06-24 18:15:36 +0000
commit324ed5a676f020e3bd4b37f40028025d1e915bbf (patch)
tree1f4c859fa21f77b99e36f9bd2885a7fe48b8f631
parenta057a4f13b2599c7fa19bf08b9617b6b3f67d2d7 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/ada/utils2.c61
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/warn5.adb34
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;