diff options
-rw-r--r-- | gcc/ada/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 18 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/trans.c | 22 |
3 files changed, 36 insertions, 15 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index ba624df07f1..54cd2dc6dda 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,6 +1,15 @@ +2016-07-14 Eric Botcazou <ebotcazou@adacore.com> + + * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Access_Type>: Also use + the void pointer type if the designated type is incomplete and has no + full view in LTO mode. + <E_Access_Protected_Subprogram_Type>: Adjust comment. + <E_Incomplete_Type>: Likewise. + * gcc-interface/trans.c (Call_to_gnu): Do not convert to the type of + the actual if it is a dummy type. + 2016-07-11 Bernd Edlinger <bernd.edlinger@hotmail.de> - Convert TYPE_ALIGN_OK to a TYPE_LANG_FLAG. * gcc-interface/ada-tree.h (TYPE_ALIGN_OK): Define. * gcc-interface/trans.c (Attribute_to_gnu): Adjust call to get_inner_reference. diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 67ba6121c56..3f468b6f5e8 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -3928,10 +3928,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) } /* If expansion is disabled, the equivalent type of a concurrent type - is absent, so build a dummy pointer type. */ + is absent, so we use the void pointer type. */ else if (type_annotate_only && No (gnat_desig_equiv)) gnu_type = ptr_type_node; + /* If the ultimately designated type is an incomplete type with no full + view, we use the void pointer type in LTO mode to avoid emitting a + dummy type in the GIMPLE IR. We cannot do that in regular mode as + the name of the dummy type in used by GDB for a global lookup. */ + else if (Ekind (gnat_desig_rep) == E_Incomplete_Type + && No (Full_View (gnat_desig_rep)) + && flag_generate_lto) + gnu_type = ptr_type_node; + /* Finally, handle the default case where we can just elaborate our designated type. */ else @@ -4017,7 +4026,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) case E_Access_Protected_Subprogram_Type: case E_Anonymous_Access_Protected_Subprogram_Type: /* If we are just annotating types and have no equivalent record type, - just return ptr_void_type. */ + just use the void pointer type. */ if (type_annotate_only && gnat_equiv_type == gnat_entity) gnu_type = ptr_type_node; @@ -4336,8 +4345,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) : Empty; /* If this is an incomplete type with no full view, it must be a Taft - Amendment type, in which case we return a dummy type. Otherwise, - just get the type from its Etype. */ + Amendment type or an incomplete type coming from a limited context, + in which cases we return a dummy type. Otherwise, we just get the + type from its Etype. */ if (No (full_view)) { if (kind == E_Incomplete_Type) diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 57d5235c4a5..b5be373a847 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -4374,7 +4374,6 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, Node_Id gnat_name = suppress_type_conversion ? Expression (gnat_actual) : gnat_actual; tree gnu_name = gnat_to_gnu (gnat_name), gnu_name_type; - tree gnu_actual; /* If it's possible we may need to use this expression twice, make sure that any side-effects are handled via SAVE_EXPRs; likewise if we need @@ -4504,7 +4503,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, } /* Start from the real object and build the actual. */ - gnu_actual = gnu_name; + tree gnu_actual = gnu_name; /* If atomic access is required for an In or In Out actual parameter, build the atomic load. */ @@ -4524,15 +4523,18 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target, /* Put back the conversion we suppressed above in the computation of the real object. And even if we didn't suppress any conversion there, we may have suppressed a conversion to the Etype of the actual earlier, - since the parent is a procedure call, so put it back here. */ - if (suppress_type_conversion - && Nkind (gnat_actual) == N_Unchecked_Type_Conversion) - gnu_actual - = unchecked_convert (gnat_to_gnu_type (Etype (gnat_actual)), - gnu_actual, No_Truncation (gnat_actual)); + since the parent is a procedure call, so put it back here. Note that + we might have a dummy type here if the actual is the dereference of a + pointer to it, but that's OK if the formal is passed by reference. */ + tree gnu_actual_type = gnat_to_gnu_type (Etype (gnat_actual)); + if (TYPE_IS_DUMMY_P (gnu_actual_type)) + gcc_assert (is_true_formal_parm && DECL_BY_REF_P (gnu_formal)); + else if (suppress_type_conversion + && Nkind (gnat_actual) == N_Unchecked_Type_Conversion) + gnu_actual = unchecked_convert (gnu_actual_type, gnu_actual, + No_Truncation (gnat_actual)); else - gnu_actual - = convert (gnat_to_gnu_type (Etype (gnat_actual)), gnu_actual); + gnu_actual = convert (gnu_actual_type, gnu_actual); /* Make sure that the actual is in range of the formal's type. */ if (Ekind (gnat_formal) != E_Out_Parameter |