diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ada/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 9 | ||||
-rw-r--r-- | gcc/stor-layout.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/array23.adb | 10 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/array23_pkg1.ads | 13 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/array23_pkg2.ads | 11 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/array23_pkg3.ads | 5 | ||||
-rw-r--r-- | gcc/tree.c | 53 | ||||
-rw-r--r-- | gcc/tree.h | 9 |
11 files changed, 107 insertions, 46 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd599e6..26f88ba 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-04-11 Eric Botcazou <ebotcazou@adacore.com> + + * stor-layout.c (skip_simple_constant_arithmetic): Move to... + * tree.c (skip_simple_constant_arithmetic): ...here and make public. + (skip_simple_arithmetic): Tidy up. + * tree.h (skip_simple_constant_arithmetic): Declare. + 2013-04-11 Naveen H.S <Naveen.Hurugalawadi@caviumnetworks.com> * config/aarch64/aarch64.h (REVERSIBLE_CC_MODE): Define. diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 53784aa..49f89b6 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2013-04-11 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.c (elaborate_expression_1): Skip only constant + arithmetics when looking for a read-only variable in the expression. + 2013-04-11 Javier Miranda <miranda@adacore.com> * check.ads, exp_ch6.adb (Install_Null_Excluding_Check): No check in diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 7342fa3..e65701b 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -6186,12 +6186,13 @@ elaborate_expression_1 (tree gnu_expr, Entity_Id gnat_entity, tree gnu_name, expr_variable_p = false; else { - /* Skip any conversions and simple arithmetics to see if the expression - is based on a read-only variable. + /* Skip any conversions and simple constant arithmetics to see if the + expression is based on a read-only variable. ??? This really should remain read-only, but we have to think about the typing of the tree here. */ - tree inner - = skip_simple_arithmetic (remove_conversions (gnu_expr, true)); + tree inner = remove_conversions (gnu_expr, true); + + inner = skip_simple_constant_arithmetic (inner); if (handled_component_p (inner)) { diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 5b89f74..67dd958 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -98,32 +98,6 @@ variable_size (tree size) /* An array of functions used for self-referential size computation. */ static GTY(()) vec<tree, va_gc> *size_functions; -/* Look inside EXPR into simple arithmetic operations involving constants. - Return the outermost non-arithmetic or non-constant node. */ - -static tree -skip_simple_constant_arithmetic (tree expr) -{ - while (true) - { - if (UNARY_CLASS_P (expr)) - expr = TREE_OPERAND (expr, 0); - else if (BINARY_CLASS_P (expr)) - { - if (TREE_CONSTANT (TREE_OPERAND (expr, 1))) - expr = TREE_OPERAND (expr, 0); - else if (TREE_CONSTANT (TREE_OPERAND (expr, 0))) - expr = TREE_OPERAND (expr, 1); - else - break; - } - else - break; - } - - return expr; -} - /* Similar to copy_tree_r but do not copy component references involving PLACEHOLDER_EXPRs. These nodes are spotted in find_placeholder_in_expr and substituted in substitute_in_expr. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ae1fd6d..21b44e7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-04-11 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/array23.adb: New test. + * gnat.dg/array23_pkg[123].ads: New helpers. + 2013-04-11 Jeff Law <law@redhat.com> PR tree-optimization/56900 diff --git a/gcc/testsuite/gnat.dg/array23.adb b/gcc/testsuite/gnat.dg/array23.adb new file mode 100644 index 0000000..2196ce5 --- /dev/null +++ b/gcc/testsuite/gnat.dg/array23.adb @@ -0,0 +1,10 @@ +-- { dg-do link } + +with Array23_Pkg1; +with Array23_Pkg2; + +procedure Array23 is + A : Array23_Pkg1.Arr; +begin + A(Array23_Pkg2.One)(1) := 0; +end; diff --git a/gcc/testsuite/gnat.dg/array23_pkg1.ads b/gcc/testsuite/gnat.dg/array23_pkg1.ads new file mode 100644 index 0000000..d0bc136 --- /dev/null +++ b/gcc/testsuite/gnat.dg/array23_pkg1.ads @@ -0,0 +1,13 @@ +with Array23_Pkg2;
+
+package Array23_Pkg1 is
+
+ C2 : Natural := Array23_Pkg2.C1;
+
+ subtype Index is Natural range 0 .. C2;
+
+ type Inner is array (Index) of Natural;
+
+ type Arr is array (Array23_Pkg2.Index) of Inner;
+
+end Array23_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/array23_pkg2.ads b/gcc/testsuite/gnat.dg/array23_pkg2.ads new file mode 100644 index 0000000..8993ffa --- /dev/null +++ b/gcc/testsuite/gnat.dg/array23_pkg2.ads @@ -0,0 +1,11 @@ +with Array23_Pkg3;
+
+package Array23_Pkg2 is
+
+ C1 : Natural := Array23_Pkg3.C0;
+
+ type Enum is (Zero, One, Two);
+
+ subtype Index is Enum range One .. Enum'val(C1);
+
+end Array23_Pkg2;
diff --git a/gcc/testsuite/gnat.dg/array23_pkg3.ads b/gcc/testsuite/gnat.dg/array23_pkg3.ads new file mode 100644 index 0000000..1a6afa8 --- /dev/null +++ b/gcc/testsuite/gnat.dg/array23_pkg3.ads @@ -0,0 +1,5 @@ +package Array23_Pkg3 is + + C0 : Natural := 2; + +end Array23_Pkg3; @@ -2830,14 +2830,12 @@ save_expr (tree expr) return t; } -/* Look inside EXPR and into any simple arithmetic operations. Return - the innermost non-arithmetic node. */ +/* Look inside EXPR into any simple arithmetic operations. Return the + outermost non-arithmetic or non-invariant node. */ tree skip_simple_arithmetic (tree expr) { - tree inner; - /* We don't care about whether this can be used as an lvalue in this context. */ while (TREE_CODE (expr) == NON_LVALUE_EXPR) @@ -2847,17 +2845,16 @@ skip_simple_arithmetic (tree expr) a constant, it will be more efficient to not make another SAVE_EXPR since it will allow better simplification and GCSE will be able to merge the computations if they actually occur. */ - inner = expr; - while (1) + while (true) { - if (UNARY_CLASS_P (inner)) - inner = TREE_OPERAND (inner, 0); - else if (BINARY_CLASS_P (inner)) + if (UNARY_CLASS_P (expr)) + expr = TREE_OPERAND (expr, 0); + else if (BINARY_CLASS_P (expr)) { - if (tree_invariant_p (TREE_OPERAND (inner, 1))) - inner = TREE_OPERAND (inner, 0); - else if (tree_invariant_p (TREE_OPERAND (inner, 0))) - inner = TREE_OPERAND (inner, 1); + if (tree_invariant_p (TREE_OPERAND (expr, 1))) + expr = TREE_OPERAND (expr, 0); + else if (tree_invariant_p (TREE_OPERAND (expr, 0))) + expr = TREE_OPERAND (expr, 1); else break; } @@ -2865,9 +2862,37 @@ skip_simple_arithmetic (tree expr) break; } - return inner; + return expr; } +/* Look inside EXPR into simple arithmetic operations involving constants. + Return the outermost non-arithmetic or non-constant node. */ + +tree +skip_simple_constant_arithmetic (tree expr) +{ + while (TREE_CODE (expr) == NON_LVALUE_EXPR) + expr = TREE_OPERAND (expr, 0); + + while (true) + { + if (UNARY_CLASS_P (expr)) + expr = TREE_OPERAND (expr, 0); + else if (BINARY_CLASS_P (expr)) + { + if (TREE_CONSTANT (TREE_OPERAND (expr, 1))) + expr = TREE_OPERAND (expr, 0); + else if (TREE_CONSTANT (TREE_OPERAND (expr, 0))) + expr = TREE_OPERAND (expr, 1); + else + break; + } + else + break; + } + + return expr; +} /* Return which tree structure is used by T. */ @@ -5339,11 +5339,16 @@ extern tree staticp (tree); extern tree save_expr (tree); -/* Look inside EXPR and into any simple arithmetic operations. Return - the innermost non-arithmetic node. */ +/* Look inside EXPR into any simple arithmetic operations. Return the + outermost non-arithmetic or non-invariant node. */ extern tree skip_simple_arithmetic (tree); +/* Look inside EXPR into simple arithmetic operations involving constants. + Return the outermost non-arithmetic or non-constant node. */ + +extern tree skip_simple_constant_arithmetic (tree); + /* Return which tree structure is used by T. */ enum tree_node_structure_enum tree_node_structure (const_tree); |