aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2017-02-24 10:00:04 +0000
committerEric Botcazou <ebotcazou@adacore.com>2017-02-24 10:00:04 +0000
commit24937f872098f27939ce0491405a965b6b31e483 (patch)
treee5293e4d0a31ed5753df85e0cae454a18c38ed30 /gcc/ada/gcc-interface/utils.c
parent8ae01e2b3b5217e22fc88d9c6da2a5459bd9035c (diff)
* gcc-interface/misc.c (gnat_type_max_size): Try to return a meaningful
value for array types with TYPE_INDEX_TYPE set on their domain type. * gcc-interface/utils.c (max_size): For operations and expressions, do not build a new node if the operands have not changed or are missing. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@245698 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r--gcc/ada/gcc-interface/utils.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 33a37cea2f6..0f4d8a4b2e6 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -3534,6 +3534,7 @@ max_size (tree exp, bool max_p)
{
enum tree_code code = TREE_CODE (exp);
tree type = TREE_TYPE (exp);
+ tree op0, op1, op2;
switch (TREE_CODE_CLASS (code))
{
@@ -3575,15 +3576,19 @@ max_size (tree exp, bool max_p)
return exp;
case tcc_comparison:
- return max_p ? size_one_node : size_zero_node;
+ return build_int_cst (type, max_p ? 1 : 0);
case tcc_unary:
if (code == NON_LVALUE_EXPR)
return max_size (TREE_OPERAND (exp, 0), max_p);
- return fold_build1 (code, type,
- max_size (TREE_OPERAND (exp, 0),
- code == NEGATE_EXPR ? !max_p : max_p));
+ op0 = max_size (TREE_OPERAND (exp, 0),
+ code == NEGATE_EXPR ? !max_p : max_p);
+
+ if (op0 == TREE_OPERAND (exp, 0))
+ return exp;
+
+ return fold_build1 (code, type, op0);
case tcc_binary:
{
@@ -3623,6 +3628,9 @@ max_size (tree exp, bool max_p)
code = PLUS_EXPR;
}
+ if (lhs == TREE_OPERAND (exp, 0) && rhs == TREE_OPERAND (exp, 1))
+ return exp;
+
/* We need to detect overflows so we call size_binop here. */
return size_binop (code, lhs, rhs);
}
@@ -3634,23 +3642,40 @@ max_size (tree exp, bool max_p)
if (code == SAVE_EXPR)
return exp;
- return fold_build1 (code, type,
- max_size (TREE_OPERAND (exp, 0),
- code == TRUTH_NOT_EXPR ? !max_p : max_p));
+ op0 = max_size (TREE_OPERAND (exp, 0),
+ code == TRUTH_NOT_EXPR ? !max_p : max_p);
+
+ if (op0 == TREE_OPERAND (exp, 0))
+ return exp;
+
+ return fold_build1 (code, type, op0);
case 2:
if (code == COMPOUND_EXPR)
return max_size (TREE_OPERAND (exp, 1), max_p);
- return fold_build2 (code, type,
- max_size (TREE_OPERAND (exp, 0), max_p),
- max_size (TREE_OPERAND (exp, 1), max_p));
+ op0 = max_size (TREE_OPERAND (exp, 0), max_p);
+ op1 = max_size (TREE_OPERAND (exp, 1), max_p);
+
+ if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
+ return exp;
+
+ return fold_build2 (code, type, op0, op1);
case 3:
if (code == COND_EXPR)
- return fold_build2 (max_p ? MAX_EXPR : MIN_EXPR, type,
- max_size (TREE_OPERAND (exp, 1), max_p),
- max_size (TREE_OPERAND (exp, 2), max_p));
+ {
+ op1 = TREE_OPERAND (exp, 1);
+ op2 = TREE_OPERAND (exp, 2);
+
+ if (!op1 || !op2)
+ return exp;
+
+ return
+ fold_build2 (max_p ? MAX_EXPR : MIN_EXPR, type,
+ max_size (op1, max_p), max_size (op2, max_p));
+ }
+ break;
default:
break;