aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_ch13.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_ch13.adb')
-rw-r--r--gcc/ada/sem_ch13.adb329
1 files changed, 316 insertions, 13 deletions
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index dcca3fc..99acbf8 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -1930,6 +1930,9 @@ package body Sem_Ch13 is
procedure Analyze_Aspect_Implicit_Dereference;
-- Perform analysis of the Implicit_Dereference aspects
+ procedure Analyze_Aspect_Potentially_Invalid;
+ -- Perform analysis of aspect Potentially_Invalid
+
procedure Analyze_Aspect_Relaxed_Initialization;
-- Perform analysis of aspect Relaxed_Initialization
@@ -2297,6 +2300,267 @@ package body Sem_Ch13 is
end Analyze_Aspect_Implicit_Dereference;
+ ----------------------------------------
+ -- Analyze_Aspect_Potentially_Invalid --
+ ----------------------------------------
+
+ procedure Analyze_Aspect_Potentially_Invalid is
+ procedure Analyze_Aspect_Parameter
+ (Subp_Id : Entity_Id;
+ Param : Node_Id;
+ Seen : in out Elist_Id);
+ -- Analyze parameter that appears in the expression of the
+ -- aspect Potentially_Invalid.
+
+ ------------------------------
+ -- Analyze_Aspect_Parameter --
+ ------------------------------
+
+ procedure Analyze_Aspect_Parameter
+ (Subp_Id : Entity_Id;
+ Param : Node_Id;
+ Seen : in out Elist_Id)
+ is
+ begin
+ -- Set name of the aspect for error messages
+ Error_Msg_Name_1 := Nam;
+
+ -- The potentially invalid parameter is a formal parameter
+
+ if Nkind (Param) in N_Identifier | N_Expanded_Name then
+ Analyze (Param);
+
+ declare
+ Item : constant Entity_Id := Entity (Param);
+ begin
+ -- It must be a formal of the analyzed subprogram
+
+ if Scope (Item) = Subp_Id then
+
+ pragma Assert (Is_Formal (Item));
+
+ -- It must not have scalar type
+
+ if Is_Scalar_Type (Underlying_Type (Etype (Item)))
+ then
+ Error_Msg_N ("illegal aspect % item", Param);
+ Error_Msg_N
+ ("\item must not have scalar type", Param);
+ end if;
+
+ -- Detect duplicated items
+
+ if Contains (Seen, Item) then
+ Error_Msg_N ("duplicate aspect % item", Param);
+ else
+ Append_New_Elmt (Item, Seen);
+ end if;
+ else
+ Error_Msg_N ("illegal aspect % item", Param);
+ end if;
+ end;
+
+ -- The potentially invalid parameter is the function's
+ -- Result attribute.
+
+ elsif Is_Attribute_Result (Param) then
+ Analyze (Param);
+
+ declare
+ Pref : constant Node_Id := Prefix (Param);
+ begin
+ if Present (Pref)
+ and then
+ Nkind (Pref) in N_Identifier | N_Expanded_Name
+ and then
+ Entity (Pref) = Subp_Id
+ then
+ -- Detect duplicated items
+
+ if Contains (Seen, Subp_Id) then
+ Error_Msg_N ("duplicate aspect % item", Param);
+ else
+ Append_New_Elmt (Entity (Pref), Seen);
+ end if;
+
+ else
+ Error_Msg_N ("illegal aspect % item", Param);
+ end if;
+ end;
+ else
+ Error_Msg_N ("illegal aspect % item", Param);
+ end if;
+ end Analyze_Aspect_Parameter;
+
+ -- Local variables
+
+ Seen : Elist_Id := No_Elist;
+ -- Items that appear in the potentially invalid aspect
+ -- expression of a subprogram; for detecting duplicates.
+
+ Restore_Scope : Boolean;
+ -- Will be set to True if we need to restore the scope table
+ -- after analyzing the aspect expression.
+
+ -- Start of processing for Analyze_Aspect_Potentially_Invalid
+
+ begin
+ -- Set name of the aspect for error messages
+ Error_Msg_Name_1 := Nam;
+
+ -- Annotation of a variable; no aspect expression is allowed
+
+ if Ekind (E) = E_Variable then
+ if Present (Expr) then
+ Error_Msg_N ("illegal aspect % expression", Expr);
+ end if;
+
+ -- Annotation of a constant; no aspect expression is allowed.
+ -- For a deferred constant, the aspect must be attached to the
+ -- partial view.
+
+ elsif Ekind (E) = E_Constant then
+ if Present (Incomplete_Or_Partial_View (E)) then
+ Error_Msg_N
+ ("aspect % must apply to deferred constant", N);
+
+ elsif Present (Expr) then
+ Error_Msg_N ("illegal aspect % expression", Expr);
+ end if;
+
+ -- Annotation of a subprogram; aspect expression is required
+
+ elsif Is_Subprogram_Or_Entry (E)
+ or else Is_Generic_Subprogram (E)
+ then
+
+ -- Not allowed for renaming declarations. Examine the
+ -- original node because a subprogram renaming may have been
+ -- rewritten as a body.
+
+ if Nkind (Original_Node (N)) in N_Renaming_Declaration then
+ Error_Msg_N
+ ("aspect % not allowed for renaming declaration",
+ Aspect);
+ end if;
+
+ if Present (Expr) then
+
+ -- If we analyze subprogram body that acts as its own
+ -- spec, then the subprogram itself and its formals are
+ -- already installed; otherwise, we need to install them,
+ -- as they must be visible when analyzing the aspect
+ -- expression.
+
+ if In_Open_Scopes (E) then
+ Restore_Scope := False;
+ else
+ Restore_Scope := True;
+ Push_Scope (E);
+
+ -- Only formals of the subprogram itself can appear
+ -- in Potentially_Invalid aspect expression, not
+ -- formals of the enclosing generic unit. (This is
+ -- different than in Precondition or Depends aspects,
+ -- where both kinds of formals are allowed.)
+
+ Install_Formals (E);
+ end if;
+
+ -- Aspect expression is either an aggregate with list of
+ -- parameters (and possibly the Result attribute for a
+ -- function).
+
+ if Nkind (Expr) = N_Aggregate then
+
+ -- Component associations in the aggregate must be a
+ -- parameter name followed by a static boolean
+ -- expression.
+
+ if Present (Component_Associations (Expr)) then
+ declare
+ Assoc : Node_Id :=
+ First (Component_Associations (Expr));
+ begin
+ while Present (Assoc) loop
+ if List_Length (Choices (Assoc)) = 1 then
+ Analyze_Aspect_Parameter
+ (E, First (Choices (Assoc)), Seen);
+
+ if Inside_A_Generic then
+ Preanalyze_And_Resolve
+ (Expression (Assoc), Any_Boolean);
+ else
+ Analyze_And_Resolve
+ (Expression (Assoc), Any_Boolean);
+ end if;
+
+ if not Is_OK_Static_Expression
+ (Expression (Assoc))
+ then
+ Error_Msg_Name_1 := Nam;
+ Flag_Non_Static_Expr
+ ("expression of aspect % " &
+ "must be static!", Aspect);
+ end if;
+
+ else
+ Error_Msg_Name_1 := Nam;
+ Error_Msg_N
+ ("illegal aspect % expression", Expr);
+ end if;
+ Next (Assoc);
+ end loop;
+ end;
+ end if;
+
+ -- Expressions of the aggregate are parameter names
+
+ if Present (Expressions (Expr)) then
+ declare
+ Param : Node_Id := First (Expressions (Expr));
+
+ begin
+ while Present (Param) loop
+ Analyze_Aspect_Parameter (E, Param, Seen);
+ Next (Param);
+ end loop;
+ end;
+ end if;
+
+ -- Mark the aggregate expression itself as analyzed;
+ -- its subexpressions were marked when they themselves
+ -- were analyzed.
+
+ Set_Analyzed (Expr);
+
+ -- Otherwise, it is a single name of a subprogram
+ -- parameter (or possibly the Result attribute for
+ -- a function).
+
+ else
+ Analyze_Aspect_Parameter (E, Expr, Seen);
+ end if;
+
+ if Restore_Scope then
+ End_Scope;
+ end if;
+
+ -- For instances of Ada.Unchecked_Conversion, allow a
+ -- parameterless aspect, as the 'Result attribute is not
+ -- defined there.
+
+ elsif Is_Unchecked_Conversion_Instance (E) then
+ null;
+ else
+ Error_Msg_N ("missing expression for aspect %", N);
+ end if;
+
+ else
+ Error_Msg_N ("inappropriate entity for aspect %", E);
+ end if;
+ end Analyze_Aspect_Potentially_Invalid;
+
-------------------------------------------
-- Analyze_Aspect_Relaxed_Initialization --
-------------------------------------------
@@ -4075,6 +4339,12 @@ package body Sem_Ch13 is
goto Continue;
+ -- Potentially_Invalid
+
+ when Aspect_Potentially_Invalid =>
+ Analyze_Aspect_Potentially_Invalid;
+ goto Continue;
+
-- SPARK_Mode
when Aspect_SPARK_Mode =>
@@ -4364,6 +4634,7 @@ package body Sem_Ch13 is
when Aspect_Designated_Storage_Model =>
if not All_Extensions_Allowed then
+ Error_Msg_Name_1 := Nam;
Error_Msg_GNAT_Extension ("aspect %", Loc);
goto Continue;
@@ -8591,6 +8862,43 @@ package body Sem_Ch13 is
Num_Repped_Components : Nat := 0;
Num_Unrepped_Components : Nat := 0;
+ function Unchecked_Union_Pragma_Pending return Boolean;
+ -- Return True in the corner case of an Unchecked_Union pragma
+ -- occuring after the record representation clause (which
+ -- means that Is_Unchecked_Union will return False for Rectype,
+ -- even though it would return True if called later after the
+ -- pragma is analyzed).
+
+ ------------------------------------
+ -- Unchecked_Union_Pragma_Pending --
+ ------------------------------------
+
+ function Unchecked_Union_Pragma_Pending return Boolean is
+ Decl_List_Element : Node_Id := N;
+ Pragma_Arg : Node_Id;
+ begin
+ while Present (Decl_List_Element) loop
+ if Nkind (Decl_List_Element) = N_Pragma
+ and then Get_Pragma_Id (Decl_List_Element) =
+ Pragma_Unchecked_Union
+ and then not Is_Empty_List (Pragma_Argument_Associations
+ (Decl_List_Element))
+ then
+ Pragma_Arg := Get_Pragma_Arg
+ (First (Pragma_Argument_Associations
+ (Decl_List_Element)));
+ if Nkind (Pragma_Arg) = N_Identifier
+ and then Chars (Pragma_Arg) = Chars (Rectype)
+ then
+ return True;
+ end if;
+ end if;
+
+ Next (Decl_List_Element);
+ end loop;
+ return False;
+ end Unchecked_Union_Pragma_Pending;
+
begin
-- First count number of repped and unrepped components
@@ -8629,8 +8937,10 @@ package body Sem_Ch13 is
-- Ignore discriminant in unchecked union, since it is
-- not there, and cannot have a component clause.
- and then (not Is_Unchecked_Union (Rectype)
- or else Ekind (Comp) /= E_Discriminant)
+ and then (Ekind (Comp) /= E_Discriminant
+ or else not (Is_Unchecked_Union (Rectype)
+ or else
+ Unchecked_Union_Pragma_Pending))
then
Error_Msg_Sloc := Sloc (Comp);
Error_Msg_NE
@@ -11136,24 +11446,16 @@ package body Sem_Ch13 is
----------------------------------
procedure Check_Aspect_At_Freeze_Point (ASN : Node_Id) is
- Ident : constant Node_Id := Identifier (ASN);
- -- Identifier (use Entity field to save expression)
-
Expr : constant Node_Id := Expression (ASN);
- -- For cases where using Entity (Identifier) doesn't work
- A_Id : constant Aspect_Id := Get_Aspect_Id (Chars (Ident));
+ A_Id : constant Aspect_Id := Get_Aspect_Id (Chars (Identifier (ASN)));
T : Entity_Id := Empty;
-- Type required for preanalyze call
begin
- -- On entry to this procedure, Entity (Ident) contains a copy of the
- -- original expression from the aspect, saved for this purpose.
-
- -- On exit from this procedure Entity (Ident) is unchanged, still
- -- containing that copy, but Expression (Ident) is a preanalyzed copy
- -- of the expression, preanalyzed just after the freeze point.
+ -- On exit from this procedure, Expression (ASN) is a copy of the
+ -- original expression, preanalyzed just after the freeze point.
-- Make a copy of the expression to be preanalyzed
@@ -11491,6 +11793,7 @@ package body Sem_Ch13 is
| Aspect_Part_Of
| Aspect_Post
| Aspect_Postcondition
+ | Aspect_Potentially_Invalid
| Aspect_Pre
| Aspect_Precondition
| Aspect_Program_Exit