From: Eric Botcazou <[email protected]>
The problem stems from an internal confusion as to whether such a type has
a dispatch table. The answer is no and the fix is to additionally prevent
the associated class-wide type from being built.
gcc/ada/ChangeLog:
* exp_ch3.adb (Expand_Freeze_Record_Type): Minor cleanup.
* sem_ch3.adb (Build_Derived_Private_Type.Copy_And_Build): Set the
Is_Implicit_Full_View flag early in the case of a record type.
(Build_Derived_Record_Type): Do not build the class-wide type for
an implicit full view.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/exp_ch3.adb | 13 +++++--------
gcc/ada/sem_ch3.adb | 19 ++++++++++++-------
2 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 2f799b0a169..ed3061cc71a 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -6548,22 +6548,19 @@ package body Exp_Ch3 is
Set_Is_Frozen (Typ);
- if not Is_Derived_Type (Typ)
- or else Is_Tagged_Type (Etype (Typ))
- then
- Set_All_DT_Position (Typ);
-
- -- If this is a type derived from an untagged private type whose
+ -- If the type is derived from an untagged private type whose
-- full view is tagged, the type is marked tagged for layout
-- reasons, but it has no dispatch table.
- elsif Is_Derived_Type (Typ)
- and then Is_Private_Type (Etype (Typ))
+ if Is_Derived_Type (Typ)
and then not Is_Tagged_Type (Etype (Typ))
then
+ pragma Assert (Is_Private_Type (Etype (Typ)));
return;
end if;
+ Set_All_DT_Position (Typ);
+
-- Create and decorate the tags. Suppress their creation when
-- not Tagged_Type_Expansion because the dispatching mechanism is
-- handled internally by the virtual target.
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index ffd42201e86..47556e147f2 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -8421,13 +8421,15 @@ package body Sem_Ch3 is
and then not Is_Generic_Type (Root_Type (Full_Parent)))
then
-- Copy and adjust declaration to provide a completion for what
- -- is originally a private declaration. Indicate that full view
- -- is internally generated.
+ -- is originally a private declaration. Indicate that the full
+ -- view is internally generated, and set Is_Implicit_Full_View
+ -- now for the sake of Build_Derived_Record_Type.
Set_Comes_From_Source (Full_N, False);
Set_Comes_From_Source (Full_Der, False);
Set_Parent (Full_Der, Full_N);
Set_Defining_Identifier (Full_N, Full_Der);
+ Set_Is_Implicit_Full_View (Full_Der);
-- If there are no constraints, adjust the subtype mark
@@ -10188,10 +10190,12 @@ package body Sem_Ch3 is
-- Set fields for tagged types
if Is_Tagged then
- -- Minor optimization: there is no need to generate the class-wide
- -- entity associated with an underlying record view.
+ -- Small optimization: there is no need to generate the class-wide
+ -- entity for either an implicit full or an underlying record view.
- if not Is_Underlying_Record_View (Derived_Type) then
+ if not Is_Implicit_Full_View (Derived_Type)
+ and then not Is_Underlying_Record_View (Derived_Type)
+ then
Make_Class_Wide_Type (Derived_Type);
end if;
@@ -10423,10 +10427,11 @@ package body Sem_Ch3 is
end if;
-- Update the class-wide type, which shares the now-completed entity
- -- list with its specific type. In case of underlying record views,
- -- we do not generate the corresponding class wide entity.
+ -- list with its specific type. But in the cases of implicit full or
+ -- underlying record views, we do not generate the class-wide type.
if Is_Tagged
+ and then not Is_Implicit_Full_View (Derived_Type)
and then not Is_Underlying_Record_View (Derived_Type)
then
Set_First_Entity
--
2.53.0