diff options
Diffstat (limited to 'gcc/ada')
-rw-r--r-- | gcc/ada/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils.cc | 17 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils2.cc | 11 | ||||
-rw-r--r-- | gcc/ada/sem_ch8.adb | 3 |
4 files changed, 39 insertions, 7 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 1ce4588..bc92ffe 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,18 @@ +2025-04-12 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/119643 + * sem_ch8.adb (Inherit_Renamed_Profile): Add guard against the + peculiarities of Natural and Positive. + +2025-04-07 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/utils.cc (convert) <POINTER_TYPE>: Use fold_convert + to convert between thin pointers. If the source is a thin pointer + with zero offset from the base and the target is a pointer to its + array, displace the pointer after converting it. + * gcc-interface/utils2.cc (build_unary_op) <ATTR_ADDR_EXPR>: Use + fold_convert to convert the address before displacing it. + 2025-04-04 Eric Botcazou <ebotcazou@adacore.com> * libgnat/a-ngcoar.adb (Eigensystem): Adjust notation and fix the diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc index 1448716..9212827 100644 --- a/gcc/ada/gcc-interface/utils.cc +++ b/gcc/ada/gcc-interface/utils.cc @@ -5259,7 +5259,7 @@ convert (tree type, tree expr) : size_zero_node; tree byte_diff = size_diffop (type_pos, etype_pos); - expr = build1 (NOP_EXPR, type, expr); + expr = fold_convert (type, expr); if (integer_zerop (byte_diff)) return expr; @@ -5267,6 +5267,21 @@ convert (tree type, tree expr) fold_convert (sizetype, byte_diff)); } + /* If converting from a thin pointer with zero offset from the base to + a pointer to the array, add the offset of the array field. */ + if (TYPE_IS_THIN_POINTER_P (etype) + && !TYPE_UNCONSTRAINED_ARRAY (TREE_TYPE (etype))) + { + tree arr_field = DECL_CHAIN (TYPE_FIELDS (TREE_TYPE (etype))); + + if (TREE_TYPE (type) == TREE_TYPE (arr_field)) + { + expr = fold_convert (type, expr); + return build_binary_op (POINTER_PLUS_EXPR, type, expr, + byte_position (arr_field)); + } + } + /* If converting fat pointer to normal or thin pointer, get the pointer to the array and then convert it. */ if (TYPE_IS_FAT_POINTER_P (etype)) diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc index 99e5927..58418ea 100644 --- a/gcc/ada/gcc-interface/utils2.cc +++ b/gcc/ada/gcc-interface/utils2.cc @@ -1628,11 +1628,12 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand) = size_binop (PLUS_EXPR, offset, size_int (bits_to_bytes_round_down (bitpos))); - /* Take the address of INNER, convert it to a pointer to our type - and add the offset. */ - inner = build_unary_op (ADDR_EXPR, - build_pointer_type (TREE_TYPE (operand)), - inner); + /* Take the address of INNER, formally convert it to a pointer + to the operand type, and finally add the offset. */ + inner = build_unary_op (ADDR_EXPR, NULL_TREE, inner); + inner + = fold_convert (build_pointer_type (TREE_TYPE (operand)), + inner); result = build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (inner), inner, offset); break; diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb index d4ab44f..0a9ef41 100644 --- a/gcc/ada/sem_ch8.adb +++ b/gcc/ada/sem_ch8.adb @@ -9314,11 +9314,12 @@ package body Sem_Ch8 is -- If the new type is a renaming of the old one, as is the case -- for actuals in instances, retain its name, to simplify later - -- disambiguation. + -- disambiguation. Beware of Natural and Positive, see Cstand. if Nkind (Parent (New_T)) = N_Subtype_Declaration and then Is_Entity_Name (Subtype_Indication (Parent (New_T))) and then Entity (Subtype_Indication (Parent (New_T))) = Old_T + and then Scope (New_T) /= Standard_Standard then null; else |