From ec1b8711945e99677fe5b135d343781bc2e106ad Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 11 Nov 2020 14:52:45 +0100 Subject: [PATCH] Fix segfault on elaboration of empty 1-element array at -O This is a rather obscure case where the elaboration of an empty array whose base type is an array type of length at most 1 goes awry when the code is compiled with optimization. gcc/ada/ChangeLog: * gcc-interface/trans.c (can_be_lower_p): Remove. (Regular_Loop_to_gnu): Add ENTRY_COND unconditionally if BOTTOM_COND is non-zero. gcc/testsuite/ChangeLog: * gnat.dg/opt89.adb: New test. --- gcc/ada/gcc-interface/trans.c | 49 +++++---------------------------- gcc/testsuite/gnat.dg/opt89.adb | 18 ++++++++++++ 2 files changed, 25 insertions(+), 42 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/opt89.adb diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index d0663a2d69b..065fcd2f956 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -2814,38 +2814,6 @@ can_equal_max_val_p (tree val, tree type, bool reverse) return can_equal_min_or_max_val_p (val, type, !reverse); } -/* Return true if VAL1 can be lower than VAL2. */ - -static bool -can_be_lower_p (tree val1, tree val2) -{ - if (TREE_CODE (val1) == NOP_EXPR) - { - tree type = TREE_TYPE (TREE_OPERAND (val1, 0)); - if (can_be_lower_p (TYPE_MAX_VALUE (type), TYPE_MIN_VALUE (type))) - return true; - - val1 = TYPE_MIN_VALUE (type); - } - - if (TREE_CODE (val1) != INTEGER_CST) - return true; - - if (TREE_CODE (val2) == NOP_EXPR) - { - tree type = TREE_TYPE (TREE_OPERAND (val2, 0)); - if (can_be_lower_p (TYPE_MAX_VALUE (type), TYPE_MIN_VALUE (type))) - return true; - - val2 = TYPE_MAX_VALUE (type); - } - - if (TREE_CODE (val2) != INTEGER_CST) - return true; - - return tree_int_cst_lt (val1, val2); -} - /* Replace EXPR1 and EXPR2 by invariant expressions if possible. Return true if both expressions have been replaced and false otherwise. */ @@ -3126,19 +3094,16 @@ Regular_Loop_to_gnu (Node_Id gnat_node, tree *gnu_cond_expr_p) } /* If we use the BOTTOM_COND, we can turn the test into an inequality - test but we may have to add ENTRY_COND to protect the empty loop. */ + test but we have to add ENTRY_COND to protect the empty loop. */ if (LOOP_STMT_BOTTOM_COND_P (gnu_loop_stmt)) { test_code = NE_EXPR; - if (can_be_lower_p (gnu_high, gnu_low)) - { - gnu_cond_expr - = build3 (COND_EXPR, void_type_node, - build_binary_op (LE_EXPR, boolean_type_node, - gnu_low, gnu_high), - NULL_TREE, alloc_stmt_list ()); - set_expr_location_from_node (gnu_cond_expr, gnat_iter_scheme); - } + gnu_cond_expr + = build3 (COND_EXPR, void_type_node, + build_binary_op (LE_EXPR, boolean_type_node, + gnu_low, gnu_high), + NULL_TREE, alloc_stmt_list ()); + set_expr_location_from_node (gnu_cond_expr, gnat_iter_scheme); } /* Open a new nesting level that will surround the loop to declare the diff --git a/gcc/testsuite/gnat.dg/opt89.adb b/gcc/testsuite/gnat.dg/opt89.adb new file mode 100644 index 00000000000..37520086616 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt89.adb @@ -0,0 +1,18 @@ +-- { dg-do run } +-- { dg-options "-O" } + +procedure Opt89 is + + type Rec is record + I : Integer := 3; + end record; + + subtype Index is Natural range 0..0; + + type Arr is array (Index range <>) of Rec; + + X : Arr (0 .. -1); + +begin + null; +end; -- 2.30.2