aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/gcc-interface/decl.c9
-rw-r--r--gcc/stor-layout.c26
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gnat.dg/array23.adb10
-rw-r--r--gcc/testsuite/gnat.dg/array23_pkg1.ads13
-rw-r--r--gcc/testsuite/gnat.dg/array23_pkg2.ads11
-rw-r--r--gcc/testsuite/gnat.dg/array23_pkg3.ads5
-rw-r--r--gcc/tree.c53
-rw-r--r--gcc/tree.h9
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;
diff --git a/gcc/tree.c b/gcc/tree.c
index ba3dcdd..d8f2424 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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. */
diff --git a/gcc/tree.h b/gcc/tree.h
index aa424c0..be43440 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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);