utils2.c (known_alignment): Derive the alignment from pointed-to types only if it...
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 24 Jun 2008 18:15:36 +0000 (18:15 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 24 Jun 2008 18:15:36 +0000 (18:15 +0000)
* 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

gcc/ada/ChangeLog
gcc/ada/utils2.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/warn5.adb [new file with mode: 0644]

index 74728b2ae3e12595be1b08be72b6462c758b19ce..be34816b3f463357ac9110321e0bb85a980a6d33 100644 (file)
@@ -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
index 891463ce49ca38dcb092860c29fbcfc60bdc2633..300fbd37d01d21517512d2a89f0365cc2a27f708 100644 (file)
@@ -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;
 }
 \f
 /* We have a comparison or assignment operation on two types, T1 and T2, which
index c7a7cd26fb42d5fa2bcc5fdf98278b2d05eb6c0c..4c569c26edb655af7139d5770f66f4ce3c54d507 100644 (file)
@@ -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 (file)
index 0000000..108bc59
--- /dev/null
@@ -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;