From: Eric Botcazou Date: Mon, 24 Nov 2025 09:36:35 +0000 (+0100) Subject: Fix wrong code for indexed component with very large index type X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=04794bba3a6b1ec68947725d973f8fb3f7ea5364;p=thirdparty%2Fgcc.git 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) : Call int_const_convert if the expression is an integer constant. gcc/testsuite/ * gnat.dg/object_overflow6.adb: New test. --- diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index 83b9e82d2dc..db736a8d26d 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 861d73ce960..85e7da595c6 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 87e7ec15157..149992d1f10 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 00000000000..8aa8e04dcc5 --- /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;