[Ada] Better diagnostics for illegal expression functions as completions.

Arnaud Charlet charlet@adacore.com
Tue Apr 25 13:05:00 GMT 2017


This patch provides a better error message on expression functions that are
completions, when the expression has a reference to a type that cannot be
frozen yet.

Compiling try.ads must yield:

   try.ads:10:49: premature usage of incomplete type "T2" defined at line 3
   try.ads:10:49: type "T2" has private component

---
package try is
   type T1 is private;
   type T2 is record
     Value     : Integer;
     Who_Knows : T1;
   end record;

   function Value (X : T2) return Integer;
   Maybe : Boolean := True;
   function Value (X : T2) return Integer is (X.Value);
private
   type T1 is new Integer;
end;

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

2017-04-25  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch6.adb (Analyze_Expression_Function): If expression function
	is completion and return type is an access type do not freeze
	designated type: this will be done in the process of freezing
	the expression if needed.
	(Freeze_Expr_Types): Check whether type is complete before
	creating freeze node, to provide a better error message if
	reference is premature.
	* sem_ch13.adb (Check_Indexing_Functions): Ignore inherited
	functions created by type derivations.

-------------- next part --------------
Index: sem_ch6.adb
===================================================================
--- sem_ch6.adb	(revision 247212)
+++ sem_ch6.adb	(working copy)
@@ -403,10 +403,6 @@
             end if;
          end if;
 
-         if Is_Access_Type (Etype (Prev)) then
-            Freeze_Before (N, Designated_Type (Etype (Prev)));
-         end if;
-
          --  For navigation purposes, indicate that the function is a body
 
          Generate_Reference (Prev, Defining_Entity (N), 'b', Force => True);
@@ -3089,7 +3085,27 @@
                elsif Ekind_In (Entity (Node), E_Component,
                                               E_Discriminant)
                then
-                  Freeze_Before (N, Scope (Entity (Node)));
+                  declare
+                     Rec : constant Entity_Id := Scope (Entity (Node));
+                  begin
+
+                     --  Check that the enclosing record type can be frozen.
+                     --  This provides a better error message than generating
+                     --  primitives whose compilation fails much later.
+                     --  Refine the error message if possible.
+
+                     Check_Fully_Declared (Rec, Node);
+
+                     if Error_Posted (Node) then
+                        if Has_Private_Component (Rec) then
+                           Error_Msg_NE ("\type& has private component",
+                             Node, Rec);
+                        end if;
+
+                     else
+                        Freeze_Before (N, Rec);
+                     end if;
+                  end;
                end if;
             end if;
 
Index: sem_ch13.adb
===================================================================
--- sem_ch13.adb	(revision 247216)
+++ sem_ch13.adb	(working copy)
@@ -4374,7 +4374,15 @@
                   --  subprogram itself.
 
                   if Is_Overloadable (It.Nam) then
-                     Check_One_Function (It.Nam);
+
+                     --  Ignore homonyms that may come from derived types
+                     --  in the context.
+
+                     if not Comes_From_Source (It.Nam) then
+                        null;
+                     else
+                        Check_One_Function (It.Nam);
+                     end if;
                   end if;
 
                   Get_Next_Interp (I, It);


More information about the Gcc-patches mailing list