-- length of the array, or its corresponding attribute.
procedure Check_Pragma_Thread_Local_Storage (Var_Id : Entity_Id);
- -- Ensure that the initialization state of variable Var_Id subject to
- -- pragma Thread_Local_Storage satisfies the semantics of the pragma.
+ -- Ensure that the initialization state of variable Var_Id subject
+ -- to pragma Thread_Local_Storage agrees with the semantics of the
+ -- pragma.
+
+ function Has_Default_Initialization
+ (Obj_Id : Entity_Id) return Boolean;
+ -- Determine whether object Obj_Id default initialized
-------------------------------
-- Check_Large_Modular_Array --
---------------------------------------
procedure Check_Pragma_Thread_Local_Storage (Var_Id : Entity_Id) is
- Decl : constant Node_Id := Declaration_Node (Var_Id);
- Expr : constant Node_Id := Expression (Decl);
+ function Has_Incompatible_Initialization
+ (Var_Decl : Node_Id) return Boolean;
+ -- Determine whether variable Var_Id with declaration Var_Decl is
+ -- initialized with a value that violates the semantics of pragma
+ -- Thread_Local_Storage.
- begin
- -- A variable whose initialization is suppressed lacks default
- -- initialization.
+ -------------------------------------
+ -- Has_Incompatible_Initialization --
+ -------------------------------------
- if Suppress_Initialization (Var_Id) then
- null;
+ function Has_Incompatible_Initialization
+ (Var_Decl : Node_Id) return Boolean
+ is
+ Init_Expr : constant Node_Id := Expression (Var_Decl);
- -- The variable has some form of initialization. Check whether it
- -- is compatible with the semantics of the pragma.
+ begin
+ -- The variable is default-initialized. This directly violates
+ -- the semantics of the pragma.
- elsif Has_Init_Expression (Decl)
- and then Present (Expr)
- and then
+ if Has_Default_Initialization (Var_Id) then
+ return True;
- -- The variable is initialized with "null"
+ -- The variable has explicit initialization. In this case only
+ -- a handful of values satisfy the semantics of the pragma.
- (Nkind (Expr) = N_Null
- or else
+ elsif Has_Init_Expression (Var_Decl)
+ and then Present (Init_Expr)
+ then
+ -- "null" is a legal form of initialization
+
+ if Nkind (Init_Expr) = N_Null then
+ return False;
- -- The variable is initialized with a static constant
+ -- A static expression is a legal form of initialization
- Is_OK_Static_Expression (Expr)
- or else
+ elsif Is_Static_Expression (Init_Expr) then
+ return False;
- -- The variable is initialized with a static aggregate
+ -- A static aggregate is a legal form of initialization
- (Nkind (Expr) = N_Aggregate
- and then Compile_Time_Known_Aggregate (Expr)))
- then
+ elsif Nkind (Init_Expr) = N_Aggregate
+ and then Compile_Time_Known_Aggregate (Init_Expr)
+ then
+ return False;
+
+ -- All other initialization expressions violate the semantic
+ -- of the pragma.
+
+ else
+ return True;
+ end if;
+
+ -- The variable lacks any kind of initialization, which agrees
+ -- with the semantics of the pragma.
+
+ else
+ return False;
+ end if;
+ end Has_Incompatible_Initialization;
+
+ -- Local declarations
+
+ Var_Decl : constant Node_Id := Declaration_Node (Var_Id);
+
+ -- Start of processing for Check_Pragma_Thread_Local_Storage
+
+ begin
+ -- A variable whose initialization is suppressed lacks any kind of
+ -- initialization.
+
+ if Suppress_Initialization (Var_Id) then
null;
- -- Otherwise the initialization of the variable violates the
- -- semantics of pragma Thread_Local_Storage.
+ -- The variable has default initialization, or is explicitly
+ -- initialized to a value other than null, static expression,
+ -- or a static aggregate.
- else
+ elsif Has_Incompatible_Initialization (Var_Decl) then
Error_Msg_NE
("Thread_Local_Storage variable& is improperly initialized",
- Decl, Var_Id);
+ Var_Decl, Var_Id);
Error_Msg_NE
("\only allowed initialization is explicit NULL, static "
- & "expression or static aggregate", Decl, Var_Id);
+ & "expression or static aggregate", Var_Decl, Var_Id);
end if;
end Check_Pragma_Thread_Local_Storage;
+ --------------------------------
+ -- Has_Default_Initialization --
+ --------------------------------
+
+ function Has_Default_Initialization
+ (Obj_Id : Entity_Id) return Boolean
+ is
+ Obj_Decl : constant Node_Id := Declaration_Node (Obj_Id);
+ Obj_Typ : constant Entity_Id := Etype (Obj_Id);
+
+ begin
+ return
+ Comes_From_Source (Obj_Id)
+ and then not Is_Imported (Obj_Id)
+ and then not Has_Init_Expression (Obj_Decl)
+ and then
+ ((Has_Non_Null_Base_Init_Proc (Obj_Typ)
+ and then not No_Initialization (Obj_Decl)
+ and then not Initialization_Suppressed (Obj_Typ))
+ or else
+ (Needs_Simple_Initialization (Obj_Typ)
+ and then not Is_Internal (Obj_Id)));
+ end Has_Default_Initialization;
+
-- Local variables
Typ : constant Entity_Id := Etype (E);
if Ekind (E) = E_Constant and then Present (Full_View (E)) then
null;
- elsif Comes_From_Source (E)
- and then not Is_Imported (E)
- and then not Has_Init_Expression (Declaration_Node (E))
- and then
- ((Has_Non_Null_Base_Init_Proc (Typ)
- and then not No_Initialization (Declaration_Node (E))
- and then not Initialization_Suppressed (Typ))
- or else
- (Needs_Simple_Initialization (Typ)
- and then not Is_Internal (E)))
- then
+ elsif Has_Default_Initialization (E) then
Check_Restriction
(No_Default_Initialization, Declaration_Node (E));
end if;