* [Ada] Expression functions as completions and private types
@ 2017-01-13 10:55 Arnaud Charlet
0 siblings, 0 replies; only message in thread
From: Arnaud Charlet @ 2017-01-13 10:55 UTC (permalink / raw)
To: gcc-patches; +Cc: Ed Schonberg
[-- Attachment #1: Type: text/plain, Size: 1200 bytes --]
An expression function that is a completion is a freeze point for all
entities referenced in its expression. As a consequence, a reference
to an uncompleted private type declared in an enclosing scope is illegal.
This patch adds the proper check to enforce this rule.
Compiling env_baselines.ads must yield:
env_baseline.ads:16:51: premature use of private type "T"
---
package Env_Baseline is
package Side is
type T is (First, Last);
end Side;
type T is private;
package General is
type T is private;
function First (Set : T) return Env_Baseline.T;
private
type T is array (Side.T) of Env_Baseline.T;
function First (Set : T) return Env_Baseline.T is (Set (Side.First));
end General;
private
type T is record
Major : Natural;
Minor : Natural;
end record;
end Env_Baseline;
Tested on x86_64-pc-linux-gnu, committed on trunk
2017-01-13 Ed Schonberg <schonberg@adacore.com>
* sem_ch6.adb (Analyze_Expression_Function): If the expression
function is a completion, all entities referenced in the
expression are frozen. As a consequence, a reference to an
uncompleted private type from an enclosing scope is illegal.
[-- Attachment #2: difs --]
[-- Type: text/plain, Size: 2047 bytes --]
Index: sem_ch6.adb
===================================================================
--- sem_ch6.adb (revision 244418)
+++ sem_ch6.adb (working copy)
@@ -274,6 +274,7 @@
New_Spec : Node_Id;
Orig_N : Node_Id;
Ret : Node_Id;
+ Ret_Type : Entity_Id;
Prev : Entity_Id;
-- If the expression is a completion, Prev is the entity whose
@@ -366,17 +367,35 @@
then
Set_Has_Completion (Prev, False);
Set_Is_Inlined (Prev);
+ Ret_Type := Etype (Prev);
-- An expression function that is a completion freezes the
- -- expression. This means freezing the return type, and if it is
- -- an access type, freezing its designated type as well.
+ -- expression. This means freezing the return type, and if it is an
+ -- access type, freezing its designated type as well.
-- Note that we cannot defer this freezing to the analysis of the
-- expression itself, because a freeze node might appear in a nested
-- scope, leading to an elaboration order issue in gigi.
- Freeze_Before (N, Etype (Prev));
+ -- An entity can only be frozen if it has a completion, so we must
+ -- check this explicitly. If it is declared elsewhere it will have
+ -- been frozen already, so only types declared in currently opend
+ -- scopes need to be tested.
+ if Ekind (Ret_Type) = E_Private_Type
+ and then In_Open_Scopes (Scope (Ret_Type))
+ and then not Is_Generic_Type (Ret_Type)
+ and then not Is_Frozen (Ret_Type)
+ and then No (Full_View (Ret_Type))
+ then
+ Error_Msg_NE
+ ("premature use of private type&",
+ Result_Definition (Specification (N)), Ret_Type);
+
+ else
+ Freeze_Before (N, Ret_Type);
+ end if;
+
if Is_Access_Type (Etype (Prev)) then
Freeze_Before (N, Designated_Type (Etype (Prev)));
end if;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2017-01-13 10:55 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-13 10:55 [Ada] Expression functions as completions and private types Arnaud Charlet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).