https://gcc.gnu.org/g:04794bba3a6b1ec68947725d973f8fb3f7ea5364
commit r16-5539-g04794bba3a6b1ec68947725d973f8fb3f7ea5364 Author: Eric Botcazou <[email protected]> Date: Mon Nov 24 10:36:35 2025 +0100 Fix wrong code for indexed component with very large index type This fixes an old issue whereby we generate wrong code in Ada for an indexed component in an array with a ludicrously large index type instead of raising Storage_Error. We would need the counterpart of int_const_binop for unop in the general case, but that's not worth the hassle and int_const_convert is good enough. gcc/ PR ada/33994 * fold-const.h (int_const_convert): New prototype. * fold-const.cc (fold_convert_const_int_from_int): Rename to... (int_const_convert): ...this, remove static keyword and add third parameter OVERFLOWABLE. (fold_convert_const): Call int_const_convert if ARG1 is an integer constant. gcc/ada/ PR ada/33994 * gcc-interface/utils.cc (convert) <INTEGER_TYPE>: Call int_const_convert if the expression is an integer constant. gcc/testsuite/ * gnat.dg/object_overflow6.adb: New test. Diff: --- gcc/ada/gcc-interface/utils.cc | 5 +++++ gcc/fold-const.cc | 14 +++++++------- gcc/fold-const.h | 1 + gcc/testsuite/gnat.dg/object_overflow6.adb | 15 +++++++++++++++ 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index 83b9e82d2dc8..db736a8d26db 100644 --- a/gcc/ada/gcc-interface/utils.cc +++ b/gcc/ada/gcc-interface/utils.cc @@ -5425,6 +5425,11 @@ convert (tree type, tree expr) return fold_convert (type, expr); } + if (TREE_CODE (expr) == INTEGER_CST) + return int_const_convert (type, expr, + type == sizetype || type == bitsizetype + ? -1 : !POINTER_TYPE_P (etype)); + /* ... fall through ... */ case ENUMERAL_TYPE: diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 861d73ce9607..85e7da595c6a 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -2183,12 +2183,12 @@ size_diffop_loc (location_t loc, tree arg0, tree arg1) MINUS_EXPR, arg1, arg0))); } - -/* A subroutine of fold_convert_const handling conversions of an - INTEGER_CST to another integer type. */ -static tree -fold_convert_const_int_from_int (tree type, const_tree arg1) +/* Convert integer constant ARG1 to TYPE, which is an integral or offset + or pointer type. */ + +tree +int_const_convert (tree type, const_tree arg1, int overflowable) { /* Given an integer constant, make new constant with new type, appropriately sign-extended or truncated. Use widest_int @@ -2197,7 +2197,7 @@ fold_convert_const_int_from_int (tree type, const_tree arg1) unsigned prec = MAX (TYPE_PRECISION (arg1_type), TYPE_PRECISION (type)); return force_fit_type (type, wide_int::from (wi::to_wide (arg1), prec, TYPE_SIGN (arg1_type)), - !POINTER_TYPE_P (TREE_TYPE (arg1)), + overflowable, TREE_OVERFLOW (arg1)); } @@ -2500,7 +2500,7 @@ fold_convert_const (enum tree_code code, tree type, tree arg1) || TREE_CODE (type) == OFFSET_TYPE) { if (TREE_CODE (arg1) == INTEGER_CST) - return fold_convert_const_int_from_int (type, arg1); + return int_const_convert (type, arg1, !POINTER_TYPE_P (arg_type)); else if (TREE_CODE (arg1) == REAL_CST) return fold_convert_const_int_from_real (code, type, arg1); else if (TREE_CODE (arg1) == FIXED_CST) diff --git a/gcc/fold-const.h b/gcc/fold-const.h index 87e7ec15157a..149992d1f107 100644 --- a/gcc/fold-const.h +++ b/gcc/fold-const.h @@ -134,6 +134,7 @@ extern bool poly_int_binop (poly_wide_int &res, enum tree_code, const_tree, const_tree, signop, wi::overflow_type *); extern tree int_const_binop (enum tree_code, const_tree, const_tree, int = 1); +extern tree int_const_convert (tree, const_tree, int = 1); #define build_fold_addr_expr(T)\ build_fold_addr_expr_loc (UNKNOWN_LOCATION, (T)) extern tree build_fold_addr_expr_loc (location_t, tree); diff --git a/gcc/testsuite/gnat.dg/object_overflow6.adb b/gcc/testsuite/gnat.dg/object_overflow6.adb new file mode 100644 index 000000000000..8aa8e04dcc5d --- /dev/null +++ b/gcc/testsuite/gnat.dg/object_overflow6.adb @@ -0,0 +1,15 @@ +-- { dg-do compile } + +with System; + +procedure Object_Overflow6 is + + type Address is range 0 .. System.Memory_Size; + + type Arr is array (Address) of Character; + + A : Arr; -- { dg-warning "Storage_Error" } + +begin + A(1) := 'a'; +end;
