This change makes it so that gigi uses a generic pointer type (ptr_type_node)
for pointers to Taft Amendment types, which are kind of opaque pointer types.
Tested on x86_64-suse-linux, applied on the mainline.
However, this isn't sufficient for LTO's type canonical merging code, because
the generic pointer type is the element type of an array instead of being used
at top level, so the code issues the usual warning:
/home/eric/svn/gcc/gcc/testsuite/gnat.dg/lto19_pkg.ads:7:13: warning: type of
'lto19_pkg__proc' does not match original declaration [-Wlto-type-mismatch]
/home/eric/svn/gcc/gcc/testsuite/gnat.dg/lto19_pkg.adb:7:3: note:
'lto19_pkg__proc' was previously declared here
/home/eric/svn/gcc/gcc/testsuite/gnat.dg/lto19_pkg.adb:7:3: note: code may be
misoptimized unless -fno-strict-aliasing is used
Jan, any idea on how to address this?
2016-07-14 Eric Botcazou <ebotca...@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-14 Eric Botcazou <ebotca...@adacore.com>
* gnat.dg/lto19.adb: New test.
* gnat.dg/lto19_pkg.ad[sb]: New helper.
--
Eric Botcazou
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c (revision 238237)
+++ gcc-interface/decl.c (working copy)
@@ -3928,10 +3928,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
}
/* 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_entit
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_entit
: 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)
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c (revision 238237)
+++ gcc-interface/trans.c (working copy)
@@ -4374,7 +4374,6 @@ Call_to_gnu (Node_Id gnat_node, tree *gn
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 *gn
}
/* 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 *gn
/* 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
-- { dg-do run }
-- { dg-options "-flto" }
-- { dg-require-effective-target lto }
with Lto19_Pkg;
procedure Lto19 is
begin
Lto19_Pkg.Proc (Lto19_Pkg.Null_Arr);
end;
package body Lto19_Pkg is
type Obj is record
I : Integer;
end record;
procedure Proc (A : Arr) is begin null; end;
end Lto19_Pkg;
package Lto19_Pkg is
type Arr is private;
Null_Arr : constant Arr;
procedure Proc (A : Arr);
private
type Obj;
type Handle is access Obj;
Null_Handle : constant Handle := null;
type Arr is array (1 .. 2) of Handle;
Null_Arr : constant Arr := (others => Null_Handle);
end Lto19_Pkg;