diff options
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/loop_unchecked_conversion.adb | 33 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/loop_unchecked_conversion.ads | 5 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 37 |
5 files changed, 81 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c866d36acec..f612b093dfe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2006-06-21 Eric Botcazou <ebotcazou@adacore.com> + + * tree-ssa-loop-ivopts.c (may_be_nonaddressable_p): New function. + (find_interesting_uses_address): Punt if above function returns true. + 2006-06-21 Richard Guenther <rguenther@suse.de> * configure: Regenerated. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 93cb39ebb46..3e9165c4afd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2006-06-21 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/loop_unchecked_conversion.ad[bs]: New test. + 2006-06-21 Joseph Myers <joseph@codesourcery.com> * gcc.c-torture/execute/complex-7.c: New. diff --git a/gcc/testsuite/gnat.dg/loop_unchecked_conversion.adb b/gcc/testsuite/gnat.dg/loop_unchecked_conversion.adb new file mode 100644 index 00000000000..e87c415c548 --- /dev/null +++ b/gcc/testsuite/gnat.dg/loop_unchecked_conversion.adb @@ -0,0 +1,33 @@ +-- { dg-do compile } +-- { dg-options "-gnatws -O" } + +with Unchecked_Conversion; + +package body loop_unchecked_conversion is + + type Byte is mod 2**8; + + type List is array (Natural range <>) of Byte; + + subtype Integer_List is List (1 .. 4); + + function Integer_Down is new + Unchecked_Conversion (Source => Integer, Target => Integer_List); + + type Storage (Size : Integer) is + record + Data : List (1 .. Size); + end record; + + type Storage_Pointer is access Storage; + + The_Data_Storage : Storage_Pointer; + + procedure slice is + begin + for I in 0 .. 1 loop + The_Data_Storage.Data (I+1 .. I+4) := Integer_Down (I); + end loop; + end; + +end loop_unchecked_conversion; diff --git a/gcc/testsuite/gnat.dg/loop_unchecked_conversion.ads b/gcc/testsuite/gnat.dg/loop_unchecked_conversion.ads new file mode 100644 index 00000000000..5ce43e5524e --- /dev/null +++ b/gcc/testsuite/gnat.dg/loop_unchecked_conversion.ads @@ -0,0 +1,5 @@ +package loop_unchecked_conversion is + + procedure slice; + +end loop_unchecked_conversion; diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 0f98604a212..8a69664ba05 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -1466,6 +1466,36 @@ may_be_unaligned_p (tree ref) return false; } +/* Return true if EXPR may be non-addressable. */ + +static bool +may_be_nonaddressable_p (tree expr) +{ + switch (TREE_CODE (expr)) + { + case COMPONENT_REF: + return DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1)) + || may_be_nonaddressable_p (TREE_OPERAND (expr, 0)); + + case ARRAY_REF: + case ARRAY_RANGE_REF: + return may_be_nonaddressable_p (TREE_OPERAND (expr, 0)); + + case VIEW_CONVERT_EXPR: + /* This kind of view-conversions may wrap non-addressable objects + and make them look addressable. After some processing the + non-addressability may be uncovered again, causing ADDR_EXPRs + of inappropriate objects to be built. */ + return AGGREGATE_TYPE_P (TREE_TYPE (expr)) + && !AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))); + + default: + break; + } + + return false; +} + /* Finds addresses in *OP_P inside STMT. */ static void @@ -1482,9 +1512,10 @@ find_interesting_uses_address (struct ivopts_data *data, tree stmt, tree *op_p) /* Ignore bitfields for now. Not really something terribly complicated to handle. TODO. */ - if (TREE_CODE (base) == BIT_FIELD_REF - || (TREE_CODE (base) == COMPONENT_REF - && DECL_NONADDRESSABLE_P (TREE_OPERAND (base, 1)))) + if (TREE_CODE (base) == BIT_FIELD_REF) + goto fail; + + if (may_be_nonaddressable_p (base)) goto fail; if (STRICT_ALIGNMENT |