From 090abb0f51b5cf8ce46fb686bc4b968f6e2055be Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:17:20 +0100 Subject: Fix problematic conversion to boolean type The new ranger exposed a problematic conversion to boolean type. gcc/ada/ChangeLog: * gcc-interface/utils.c (convert) : Call fold_convert in the cases where convert_to_integer is not called. : Call fold_convert instead of convert_to_integer. --- gcc/ada/gcc-interface/utils.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'gcc/ada/gcc-interface') diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 013fccd..1d49db9 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -4930,10 +4930,6 @@ convert (tree type, tree expr) convert (TREE_TYPE (type), TYPE_MIN_VALUE (type)))); - /* ... fall through ... */ - - case ENUMERAL_TYPE: - case BOOLEAN_TYPE: /* If we are converting an additive expression to an integer type with lower precision, be wary of the optimization that can be applied by convert_to_integer. There are 2 problematic cases: @@ -4945,8 +4941,7 @@ convert (tree type, tree expr) intermediate conversion that changes the sign could be inserted and thus introduce an artificial overflow at compile time when the placeholder is substituted. */ - if (code == INTEGER_TYPE - && ecode == INTEGER_TYPE + if (ecode == INTEGER_TYPE && TYPE_PRECISION (type) < TYPE_PRECISION (etype) && (TREE_CODE (expr) == PLUS_EXPR || TREE_CODE (expr) == MINUS_EXPR)) { @@ -4955,11 +4950,18 @@ convert (tree type, tree expr) if ((TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (TREE_TYPE (op0))) || CONTAINS_PLACEHOLDER_P (expr)) - return build1 (NOP_EXPR, type, expr); + return fold_convert (type, expr); } + /* ... fall through ... */ + + case ENUMERAL_TYPE: return fold (convert_to_integer (type, expr)); + case BOOLEAN_TYPE: + /* Do not use convert_to_integer with boolean types. */ + return fold_convert_loc (EXPR_LOCATION (expr), type, expr); + case POINTER_TYPE: case REFERENCE_TYPE: /* If converting between two thin pointers, adjust if needed to account -- cgit v1.1 From 02221bed3c4912d59a865fa69bf12f54c980f957 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:30:05 +0100 Subject: Fix corner case issue with discriminated record type The compiler generates code that writes too much data into a component of a record subject to a representation clause, when the source of the assignment is a call to a function that returns a discriminated record type with default discriminants, variable size and a statically known upper bound for this size, and the size of the component given by the representation clause is lower than the value of this bound rounded up to the alignment. gcc/ada/ChangeLog: * gcc-interface/trans.c (Call_to_gnu): Also create a temporary for the return value if the LHS is a bit-field and the return type is a type padding a self-referential type. (gnat_to_gnu): Do not remove the padding on the result if it is too small with regard to the natural padding size. --- gcc/ada/gcc-interface/trans.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'gcc/ada/gcc-interface') diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 0eec178..07e5a28 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -4513,7 +4513,11 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, and the return type has variable size, because the gimplifier doesn't handle these cases. - 4. There is no target and we have misaligned In Out or Out parameters + 4. There is a target which is a bit-field and the function returns an + unconstrained record type with default discriminant, because the + return may copy more data than the bit-field can contain. + + 5. There is no target and we have misaligned In Out or Out parameters passed by reference, because we need to preserve the return value before copying back the parameters. However, in this case, we'll defer creating the temporary, see below. @@ -4536,7 +4540,11 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, || (TREE_CODE (TREE_TYPE (gnu_target)) == ARRAY_TYPE && TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_target))) == INTEGER_CST)) - && TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST))) + && TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST) + || (gnu_target + && TREE_CODE (gnu_target) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (gnu_target, 1)) + && type_is_padding_self_referential (gnu_result_type)))) { gnu_retval = create_temporary ("R", gnu_result_type); DECL_RETURN_VALUE_P (gnu_retval) = 1; @@ -8249,8 +8257,10 @@ gnat_to_gnu (Node_Id gnat_node) /* Remove padding only if the inner object is of self-referential size: in that case it must be an object of unconstrained type with a default discriminant and we want to avoid copying too - much data. */ - if (type_is_padding_self_referential (TREE_TYPE (gnu_result))) + much data. But do not remove it if it is already too small. */ + if (type_is_padding_self_referential (TREE_TYPE (gnu_result)) + && !(TREE_CODE (gnu_result) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (gnu_result, 1)))) gnu_result = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_result))), gnu_result); } -- cgit v1.1 From 6fb8da750ff53faec52aaa6cda31fbc510219926 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:34:31 +0100 Subject: Fix oversight in earlier change gcc/ada/ChangeLog: * gcc-interface/decl.c (gnat_to_gnu_entity) : Put back the "else" unduly removed. --- gcc/ada/gcc-interface/decl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/ada/gcc-interface') diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index a0f17b1..7caca6a 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -1764,6 +1764,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) /* Use the arbitrary scale factor description. Note that we support a Small_Value whose magnitude is larger than 64-bit even on 32-bit platforms, so we unconditionally use a (dummy) 128-bit type. */ + else { const Uint gnat_num = Norm_Num (gnat_small_value); const Uint gnat_den = Norm_Den (gnat_small_value); -- cgit v1.1 From 6a1e04b2f0c28d46e193d30aac00a32ba850bf0a Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:40:23 +0100 Subject: Fix assembler name collision Gigi uses a dummy global variable to register global types for debug info purposes and its name can now collide with user variables. gcc/ada/ChangeLog: * gcc-interface/trans.c (lvalue_for_aggregate_p): Also return true for return statements. * gcc-interface/utils.c (gnat_write_global_declarations): Use the maximum index for the dummy object to avoid a name collision. --- gcc/ada/gcc-interface/trans.c | 4 ++++ gcc/ada/gcc-interface/utils.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'gcc/ada/gcc-interface') diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 07e5a28..bf8289b 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -970,6 +970,10 @@ lvalue_for_aggregate_p (Node_Id gnat_node, tree gnu_type) /* Even if the parameter is by copy, prefer an lvalue. */ return true; + case N_Simple_Return_Statement: + /* Likewise for a return value. */ + return true; + case N_Indexed_Component: case N_Selected_Component: /* If an elementary component is used, take it from the constant. */ diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index 1d49db9..494f60e 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -5903,7 +5903,7 @@ gnat_write_global_declarations (void) struct varpool_node *node; char *label; - ASM_FORMAT_PRIVATE_NAME (label, first_global_object_name, 0); + ASM_FORMAT_PRIVATE_NAME (label, first_global_object_name, ULONG_MAX); dummy_global = build_decl (BUILTINS_LOCATION, VAR_DECL, get_identifier (label), void_type_node); -- cgit v1.1 From 67c4d1c7addc88c2d133731cf81ffad7d50fa8b9 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:48:06 +0100 Subject: Fix internal error on library-level type extended locally The compiler aborts on the local extension of a tagged type declared at library level, with a progenitor given by an interface type having a primitive that is a homograph of a primitive of the tagged type. gcc/ada/ChangeLog: * gcc-interface/trans.c (maybe_make_gnu_thunk): Return false if the target is local and thunk and target do not have the same context. --- gcc/ada/gcc-interface/trans.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'gcc/ada/gcc-interface') diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index bf8289b..4ab26d3 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -10730,8 +10730,11 @@ maybe_make_gnu_thunk (Entity_Id gnat_thunk, tree gnu_thunk) tree gnu_target = gnat_to_gnu_entity (gnat_target, NULL_TREE, false); - /* Thunk and target must have the same nesting level, if any. */ - gcc_assert (DECL_CONTEXT (gnu_thunk) == DECL_CONTEXT (gnu_target)); + /* If the target is local, then thunk and target must have the same context + because cgraph_node::expand_thunk can only forward the static chain. */ + if (DECL_STATIC_CHAIN (gnu_target) + && DECL_CONTEXT (gnu_thunk) != DECL_CONTEXT (gnu_target)) + return false; /* If the target returns by invisible reference and is external, apply the same transformation as Subprogram_Body_to_gnu here. */ -- cgit v1.1 From f8fb01fbb0c3c6b8ec0e5a301651b0824aaf880b Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 7 Dec 2020 10:56:05 +0100 Subject: Housekeeping work in gigi gcc/ada/ChangeLog: * gcc-interface/Make-lang.in: Remove ^L characters. * gcc-interface/decl.c (create_concat_name): Add cast. --- gcc/ada/gcc-interface/Make-lang.in | 7 +++---- gcc/ada/gcc-interface/decl.c | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'gcc/ada/gcc-interface') diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index 89b5750..d88c354 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -42,7 +42,7 @@ MV = mv MKDIR = mkdir -p RM = rm -f RMDIR = rm -rf - + # Extra flags to pass to recursive makes. COMMON_ADAFLAGS= -gnatpg @@ -814,7 +814,6 @@ doc/gnat_rm.pdf: ada/gnat_rm.texi $(gcc_docdir)/include/fdl.texi \ doc/gnat-style.pdf: ada/gnat-style.texi $(gcc_docdir)/include/fdl.texi $(TEXI2PDF) -c -I $(abs_docdir)/include -o $@ $< - # Install hooks: # gnat1 is installed elsewhere as part of $(COMPILERS). @@ -908,7 +907,7 @@ ada.maintainer-clean: -$(RM) ada/nmake.ads -$(RM) ada/treeprs.ads -$(RM) ada/snames.ads ada/snames.adb ada/snames.h - + # Stage hooks: # The main makefile has already created stage?/ada @@ -1005,7 +1004,7 @@ $(check_acats_targets): check-acats%: touch $$GCC_RUNTEST_PARALLELIZE_DIR/finished .PHONY: check-acats $(check_acats_targets) - + # Compiling object files from source files. # Ada language specific files. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 7caca6a..5ea1b16 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -10353,7 +10353,7 @@ create_concat_name (Entity_Id gnat_entity, const char *suffix) { const Entity_Kind kind = Ekind (gnat_entity); const bool has_suffix = (suffix != NULL); - String_Template temp = {1, has_suffix ? strlen (suffix) : 0}; + String_Template temp = {1, has_suffix ? (int) strlen (suffix) : 0}; String_Pointer sp = {suffix, &temp}; Get_External_Name (gnat_entity, has_suffix, sp); -- cgit v1.1