From: Javier Miranda <[email protected]>

This patch fixed a compiler crash when allocating a tagged record
types through class-wide access type.

gcc/ada/ChangeLog:

        * exp_ch4.adb (Expand_N_Allocator): For a class-wide designated
        type with a constructor initializer, add a type conversion to
        the specific type to avoid a dispatching call (since contructors
        are not dispatching primitives).
        * sem_ch13.adb (Analyze_Aspect_Specifications)
        <Aspect_Initialize>: Avoid reporting a spurious error.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_ch4.adb  | 12 ++++++++++++
 gcc/ada/sem_ch13.adb |  4 +++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index e139c89e2a3..1148fc21ad1 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -4948,6 +4948,18 @@ package body Exp_Ch4 is
 
                if Is_Incomplete_Or_Private_Type (Designated_Type (PtrT)) then
                   Deref := Unchecked_Convert_To (Etype (Init_Expr), Deref);
+
+               --  For a class-wide designated type with a constructor-based
+               --  initializer, convert to the specific type to avoid a
+               --  dispatching constructor call. Constructors are not
+               --  dispatching primitives, so the call must target the
+               --  specific type directly.
+
+               elsif Is_Class_Wide_Type (Designated_Type (PtrT))
+                 and then Nkind (Init_Expr) = N_Attribute_Reference
+                 and then Attribute_Name (Init_Expr) = Name_Make
+               then
+                  Deref := Unchecked_Convert_To (Etyp, Deref);
                end if;
 
                Stmt :=
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 47230c2f4d7..eda8f58a64b 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -4901,7 +4901,9 @@ package body Sem_Ch13 is
 
             Typ := Etype (First_Entity (E));
 
-            if No (First_Entity (Typ)) then
+            if Comes_From_Source (Aspect)
+              and then No (First_Entity (Typ))
+            then
                Error_Msg_N
                  ("Initialize can only apply to contructors"
                    & " whose type has one or more components", N);
-- 
2.53.0

Reply via email to