+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.
+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
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))
{
/* 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. */
+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
--- /dev/null
+-- { dg-do link }
+
+with Array23_Pkg1;
+with Array23_Pkg2;
+
+procedure Array23 is
+ A : Array23_Pkg1.Arr;
+begin
+ A(Array23_Pkg2.One)(1) := 0;
+end;
--- /dev/null
+with Array23_Pkg2;\r
+\r
+package Array23_Pkg1 is\r
+\r
+ C2 : Natural := Array23_Pkg2.C1;\r
+\r
+ subtype Index is Natural range 0 .. C2;\r
+\r
+ type Inner is array (Index) of Natural;\r
+\r
+ type Arr is array (Array23_Pkg2.Index) of Inner;\r
+\r
+end Array23_Pkg1;\r
--- /dev/null
+with Array23_Pkg3;\r
+\r
+package Array23_Pkg2 is\r
+\r
+ C1 : Natural := Array23_Pkg3.C0;\r
+\r
+ type Enum is (Zero, One, Two);\r
+\r
+ subtype Index is Enum range One .. Enum'val(C1);\r
+\r
+end Array23_Pkg2;\r
--- /dev/null
+package Array23_Pkg3 is
+
+ C0 : Natural := 2;
+
+end Array23_Pkg3;
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)
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;
}
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. */
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);