diff mbox

[Ada] Crash on illegal allocator for limited type.

Message ID 20160502103658.GA23343@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet May 2, 2016, 10:36 a.m. UTC
This patch fixes a compiler crash on an allocator for an object of a limited
type, when the expression of the qualified expression is a type conversion.

Compiling bug1.adb must yield:
bug1.adb:29:08: illegal expression
  for initialized allocator of a limited type (RM 7.5 (2.7/2))

---
pragma Ada_2012;
procedure Bug1 is
   package Interf is
      type T is limited interface;
      subtype Implementor is T'Class;
      function Init return T is abstract;
   end Interf;

   package Impl is
      type T is limited new Interf.T with private;
      overriding function Init return T;
   private
      type T is limited new Interf.T with null record;
   end Impl;

   package body Impl is
      function Init return T is
      begin
         return Obj : T do
            null;
         end return;
      end Init;
   end Impl;
   use Impl;

   V : access Interf.T'Class;
   Thing : T := Init;
begin
  V := new Interf.T'class'(Interf.Implementor(Impl.Init));  
end Bug1;

Tested on x86_64-pc-linux-gnu, committed on trunk

2016-05-02  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch3.adb (OK_For_Limited_Init): A type conversion is not
	always legal in the in-place initialization of a limited entity
	(e.g. an allocator).
	* sem_res.adb (Resolve_Allocator): Improve error message with RM
	reference  when allocator expression is illegal.
diff mbox

Patch

Index: sem_ch3.adb
===================================================================
--- sem_ch3.adb	(revision 235740)
+++ sem_ch3.adb	(working copy)
@@ -18656,11 +18656,14 @@ 
    is
    begin
       --  An object of a limited interface type can be initialized with any
-      --  expression of a nonlimited descendant type.
+      --  expression of a nonlimited descendant type. However this does not
+      --  apply if this is a view conversion of some other expression. This
+      --  is checked below.
 
       if Is_Class_Wide_Type (Typ)
         and then Is_Limited_Interface (Typ)
         and then not Is_Limited_Type (Etype (Exp))
+        and then Nkind (Exp) /= N_Type_Conversion
       then
          return True;
       end if;
Index: sem_res.adb
===================================================================
--- sem_res.adb	(revision 235714)
+++ sem_res.adb	(working copy)
@@ -4767,13 +4767,21 @@ 
            and then not In_Instance_Body
          then
             if not OK_For_Limited_Init (Etype (E), Expression (E)) then
-               Error_Msg_N ("initialization not allowed for limited types", N);
+               if Nkind (Parent (N)) = N_Assignment_Statement then
+                  Error_Msg_N
+                    ("illegal expression for initialized allocator of a "
+                     & "limited type (RM 7.5 (2.7/2))", N);
+               else
+                  Error_Msg_N
+                    ("initialization not allowed for limited types", N);
+               end if;
+
                Explain_Limited_Type (Etype (E), N);
             end if;
          end if;
 
-         --  A qualified expression requires an exact match of the type.
-         --  Class-wide matching is not allowed.
+         --  A qualified expression requires an exact match of the type. Class-
+         --  wide matching is not allowed.
 
          if (Is_Class_Wide_Type (Etype (Expression (E)))
               or else Is_Class_Wide_Type (Etype (E)))