diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index ac954d2b04a..af3b9280b4f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2017-09-05 Eric Botcazou + + PR ada/62235 + * gcc-interface/decl.c (gnat_to_gnu_entity): Skip regular processing + for Itypes that are E_Record_Subtype with a cloned subtype. + : Use the DECL of the cloned type directly, if any. + 2017-09-05 Eric Botcazou * gcc-interface/trans.c (convert_with_check): Use a custom base type diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 569fe859d4e..a7272e4ae8e 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -312,11 +312,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) /* Since a use of an Itype is a definition, process it as such if it is in the main unit, except for E_Access_Subtype because it's actually a use - of its base type, see below. */ + of its base type, and for E_Record_Subtype with cloned subtype because + it's actually a use of the cloned subtype, see below. */ if (!definition && is_type && Is_Itype (gnat_entity) - && Ekind (gnat_entity) != E_Access_Subtype + && !(kind == E_Access_Subtype + || (kind == E_Record_Subtype + && Present (Cloned_Subtype (gnat_entity)))) && !present_gnu_tree (gnat_entity) && In_Extended_Main_Code_Unit (gnat_entity)) { @@ -3411,7 +3414,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) { gnu_decl = gnat_to_gnu_entity (Cloned_Subtype (gnat_entity), NULL_TREE, false); - maybe_present = true; + saved = true; break; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 68c4076278d..0ef3da8691b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-09-05 Eric Botcazou + + * gnat.dg/incomplete5.ad[sb]: New test. + * gnat.dg/incomplete5_pkg.ad[sb]: New helper. + 2017-09-05 Eric Botcazou * gnat.dg/specs/uc2.ads: New test. diff --git a/gcc/testsuite/gnat.dg/incomplete5.adb b/gcc/testsuite/gnat.dg/incomplete5.adb new file mode 100644 index 00000000000..f6b4879dc00 --- /dev/null +++ b/gcc/testsuite/gnat.dg/incomplete5.adb @@ -0,0 +1,10 @@ +-- { dg-do compile } + +package body Incomplete5 is + + function Get (O: Base_Object) return Integer is + begin + return Get_Handle(O).I; + end; + +end Incomplete5; diff --git a/gcc/testsuite/gnat.dg/incomplete5.ads b/gcc/testsuite/gnat.dg/incomplete5.ads new file mode 100644 index 00000000000..0e0394212c8 --- /dev/null +++ b/gcc/testsuite/gnat.dg/incomplete5.ads @@ -0,0 +1,25 @@ +with Incomplete5_Pkg; + +package Incomplete5 is + + type Rec1 is private; + + type Rec2 is private; + + package My_G is new Incomplete5_Pkg (Rec1); + + use My_G; + + function Get (O: Base_Object) return Integer; + +private + + type Rec1 is record + I : Integer; + end record; + + type Rec2 is record + A : Access_Type; + end record; + +end Incomplete5; diff --git a/gcc/testsuite/gnat.dg/incomplete5_pkg.adb b/gcc/testsuite/gnat.dg/incomplete5_pkg.adb new file mode 100644 index 00000000000..44b1411e404 --- /dev/null +++ b/gcc/testsuite/gnat.dg/incomplete5_pkg.adb @@ -0,0 +1,13 @@ +package body Incomplete5_Pkg is + + function Get_Handle (Object: Base_Object) return Access_Type is + begin + return Object.Handle; + end; + + function From_Handle (Handle: Access_Type) return Base_Object is + begin + return (Handle=>Handle); + end; + +end Incomplete5_Pkg; diff --git a/gcc/testsuite/gnat.dg/incomplete5_pkg.ads b/gcc/testsuite/gnat.dg/incomplete5_pkg.ads new file mode 100644 index 00000000000..28f3809d746 --- /dev/null +++ b/gcc/testsuite/gnat.dg/incomplete5_pkg.ads @@ -0,0 +1,15 @@ +generic + type Record_Type; +package Incomplete5_Pkg is + + type Access_Type is access Record_Type; + + type Base_Object is tagged record + Handle: Access_Type; + end record; + + function Get_Handle(Object: Base_Object) return Access_Type; + + function From_Handle(Handle: Access_Type) return Base_Object; + +end Incomplete5_Pkg;