> 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.
The early return for the these types in Expand_Freeze_Record_Type comes too
late and leaves declarations of primitive operations without a completion.
Tested on x86-64/Linux, applied on the mainline.
2026-09-22 Eric Botcazou <[email protected]>
* exp_ch3.adb (Expand_Freeze_Record_Type): Move up early return for
types derived from an untagged private type.
--
Eric Botcazoudiff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 3b823b6fa41..de771f02568 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -6456,6 +6456,17 @@ package body Exp_Ch3 is
Set_CPP_Constructors (Typ);
else
+ -- 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.
+
+ if Is_Derived_Type (Typ)
+ and then not Is_Tagged_Type (Etype (Typ))
+ then
+ pragma Assert (Is_Private_Type (Etype (Typ)));
+ return;
+ end if;
+
if not Building_Static_DT (Typ) then
-- Usually inherited primitives are not delayed but the first
@@ -6548,17 +6559,6 @@ package body Exp_Ch3 is
Set_Is_Frozen (Typ);
- -- 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.
-
- 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