Commit 51ab2a39 by Javier Miranda Committed by Pierre-Marie de Rodat

[Ada] Restrict initialization of External_Tag and Expanded_Name

2018-05-23  Javier Miranda  <miranda@adacore.com>

gcc/ada/

	* exp_disp.adb (Make_DT): Restrict the initialization of
	External_Tag and Expanded_Name to an empty string to the case where
	both pragmas apply (i.e. No_Tagged_Streams and Discard_Names), since
	restricted runtimes are compiled with pragma Discard_Names.
	* doc/gnat_rm/implementation_defined_pragmas.rst,
	doc/gnat_rm/implementation_defined_characteristics.rst: Add
	documentation.
	* gnat_rm.texi: Regenerate.

From-SVN: r260584
parent 6734617c
2018-05-23 Javier Miranda <miranda@adacore.com>
* exp_disp.adb (Make_DT): Restrict the initialization of
External_Tag and Expanded_Name to an empty string to the case where
both pragmas apply (i.e. No_Tagged_Streams and Discard_Names), since
restricted runtimes are compiled with pragma Discard_Names.
* doc/gnat_rm/implementation_defined_pragmas.rst,
doc/gnat_rm/implementation_defined_characteristics.rst: Add
documentation.
* gnat_rm.texi: Regenerate.
2018-05-23 Maroua Maalej <maalej@adacore.com> 2018-05-23 Maroua Maalej <maalej@adacore.com>
* sem_spark.adb: Fix of some permission rules of pointers in SPARK. * sem_spark.adb: Fix of some permission rules of pointers in SPARK.
......
...@@ -875,6 +875,11 @@ be suppressed. In the presence of this pragma, the Image attribute ...@@ -875,6 +875,11 @@ be suppressed. In the presence of this pragma, the Image attribute
provides the image of the Pos of the literal, and Value accepts provides the image of the Pos of the literal, and Value accepts
Pos values. Pos values.
For tagged types, when pragmas ``Discard_Names`` and ``No_Tagged_Streams``
simultaneously apply, their Expanded_Name and External_Tag are initialized
with empty strings. This is useful to avoid exposing entity names at binary
level.
* *
"The result of the ``Task_Identification.Image`` "The result of the ``Task_Identification.Image``
attribute. See C.7.1(7)." attribute. See C.7.1(7)."
......
...@@ -3892,6 +3892,11 @@ and derived types of this type inherit the pragma automatically, so the effect ...@@ -3892,6 +3892,11 @@ and derived types of this type inherit the pragma automatically, so the effect
applies to a complete hierarchy (this is necessary to deal with the class-wide applies to a complete hierarchy (this is necessary to deal with the class-wide
dispatching versions of the stream routines). dispatching versions of the stream routines).
When pragmas ``Discard_Names`` and ``No_Tagged_Streams`` are simultaneously
applied to a tagged type its Expanded_Name and External_Tag are initialized
with empty strings. This is useful to avoid exposing entity names at binary
level but has a negative impact on the debuggability of tagged types.
Pragma Normalize_Scalars Pragma Normalize_Scalars
======================== ========================
......
...@@ -4480,6 +4480,21 @@ package body Exp_Disp is ...@@ -4480,6 +4480,21 @@ package body Exp_Disp is
Result : constant List_Id := New_List; Result : constant List_Id := New_List;
Tname : constant Name_Id := Chars (Typ); Tname : constant Name_Id := Chars (Typ);
-- When pragmas Discard_Names and No_Tagged_Streams simultaneously apply
-- we initialize the Expanded_Name and the External_Tag of this tagged
-- type with an empty string. This is useful to avoid exposing entity
-- names at binary level. It can be done when both pragmas apply because
-- (1) Discard_Names allows initializing Expanded_Name with an
-- implementation defined value (Ada RM Section C.5 (7/2)).
-- (2) External_Tag (combined with Internal_Tag) is used for object
-- streaming and No_Tagged_Streams inhibits the generation of
-- streams.
Discard_Names : constant Boolean :=
Present (No_Tagged_Streams_Pragma (Typ))
and then (Global_Discard_Names
or else Einfo.Discard_Names (Typ));
-- The following name entries are used by Make_DT to generate a number -- The following name entries are used by Make_DT to generate a number
-- of entities related to a tagged type. These entities may be generated -- of entities related to a tagged type. These entities may be generated
-- in a scope other than that of the tagged type declaration, and if -- in a scope other than that of the tagged type declaration, and if
...@@ -4511,8 +4526,7 @@ package body Exp_Disp is ...@@ -4511,8 +4526,7 @@ package body Exp_Disp is
DT_Aggr_List : List_Id; DT_Aggr_List : List_Id;
DT_Constr_List : List_Id; DT_Constr_List : List_Id;
DT_Ptr : Entity_Id; DT_Ptr : Entity_Id;
Expanded_Name : Entity_Id; Exname : Entity_Id;
External_Tag_Name : Entity_Id;
HT_Link : Entity_Id; HT_Link : Entity_Id;
ITable : Node_Id; ITable : Node_Id;
I_Depth : Nat := 0; I_Depth : Nat := 0;
...@@ -4591,44 +4605,12 @@ package body Exp_Disp is ...@@ -4591,44 +4605,12 @@ package body Exp_Disp is
end if; end if;
end if; end if;
DT := Make_Defining_Identifier (Loc, Name_DT); DT := Make_Defining_Identifier (Loc, Name_DT);
Expanded_Name := Make_Defining_Identifier (Loc, Name_Exname); Exname := Make_Defining_Identifier (Loc, Name_Exname);
HT_Link := Make_Defining_Identifier (Loc, Name_HT_Link); HT_Link := Make_Defining_Identifier (Loc, Name_HT_Link);
Predef_Prims := Make_Defining_Identifier (Loc, Name_Predef_Prims); Predef_Prims := Make_Defining_Identifier (Loc, Name_Predef_Prims);
SSD := Make_Defining_Identifier (Loc, Name_SSD); SSD := Make_Defining_Identifier (Loc, Name_SSD);
TSD := Make_Defining_Identifier (Loc, Name_TSD); TSD := Make_Defining_Identifier (Loc, Name_TSD);
-- Expanded_Name
-- -------------
-- We generally initialize the Expanded_Name and the External_Tag of
-- tagged types with the same name, unless pragmas Discard_Names or
-- No_Tagged_Streams apply: Discard_Names allows us to initialize its
-- Expanded_Name with an empty string because in such a case it's
-- value is implementation defined (Ada RM Section C.5(7/2)); pragma
-- No_Tagged_Streams inhibits the generation of stream routines and
-- we initialize its External_Tag with an empty string since Ada.Tags
-- services Internal_Tag and External_Tag are mainly used with streams.
-- Small optimization: when both pragmas apply then there is no need to
-- declare two objects initialized with empty strings (since the two
-- aggregate components can be initialized with the same object).
if (Global_Discard_Names or else Discard_Names (Typ))
and then Present (No_Tagged_Streams_Pragma (Typ))
then
External_Tag_Name := Expanded_Name;
elsif Global_Discard_Names
or else Discard_Names (Typ)
or else Present (No_Tagged_Streams_Pragma (Typ))
then
External_Tag_Name :=
Make_Defining_Identifier (Loc,
New_External_Name (Tname, 'N', Suffix_Index => -1));
else
External_Tag_Name := Expanded_Name;
end if;
-- Initialize Parent_Typ handling private types -- Initialize Parent_Typ handling private types
...@@ -5033,27 +5015,25 @@ package body Exp_Disp is ...@@ -5033,27 +5015,25 @@ package body Exp_Disp is
end if; end if;
end if; end if;
-- Generate: -- Generate: Expanded_Name : constant String := "";
-- Expanded_Name : constant String := "";
if Global_Discard_Names or else Discard_Names (Typ) then if Discard_Names then
Append_To (Result, Append_To (Result,
Make_Object_Declaration (Loc, Make_Object_Declaration (Loc,
Defining_Identifier => Expanded_Name, Defining_Identifier => Exname,
Constant_Present => True, Constant_Present => True,
Object_Definition => New_Occurrence_Of (Standard_String, Loc), Object_Definition => New_Occurrence_Of (Standard_String, Loc),
Expression => Expression =>
Make_String_Literal (Loc, ""))); Make_String_Literal (Loc, "")));
-- Generate: -- Generate: Exname : constant String := full_qualified_name (typ);
-- Expanded_Name : constant String := full_qualified_name (typ);
-- The type itself may be an anonymous parent type, so use the first -- The type itself may be an anonymous parent type, so use the first
-- subtype to have a user-recognizable name. -- subtype to have a user-recognizable name.
else else
Append_To (Result, Append_To (Result,
Make_Object_Declaration (Loc, Make_Object_Declaration (Loc,
Defining_Identifier => Expanded_Name, Defining_Identifier => Exname,
Constant_Present => True, Constant_Present => True,
Object_Definition => New_Occurrence_Of (Standard_String, Loc), Object_Definition => New_Occurrence_Of (Standard_String, Loc),
Expression => Expression =>
...@@ -5061,46 +5041,8 @@ package body Exp_Disp is ...@@ -5061,46 +5041,8 @@ package body Exp_Disp is
Fully_Qualified_Name_String (First_Subtype (Typ))))); Fully_Qualified_Name_String (First_Subtype (Typ)))));
end if; end if;
Set_Is_Statically_Allocated (Expanded_Name); Set_Is_Statically_Allocated (Exname);
Set_Is_True_Constant (Expanded_Name); Set_Is_True_Constant (Exname);
-- Generate the External_Tag name only when it is required (since in
-- most cases we can initialize Expanded_Name and External_Tag using
-- the same object).
if Expanded_Name /= External_Tag_Name then
-- Generate:
-- External_Tag_Name : constant String := "";
if Present (No_Tagged_Streams_Pragma (Typ)) then
Append_To (Result,
Make_Object_Declaration (Loc,
Defining_Identifier => External_Tag_Name,
Constant_Present => True,
Object_Definition =>
New_Occurrence_Of (Standard_String, Loc),
Expression => Make_String_Literal (Loc, "")));
-- Generate:
-- External_Tag_Name : constant String :=
-- full_qualified_name (typ);
else
Append_To (Result,
Make_Object_Declaration (Loc,
Defining_Identifier => External_Tag_Name,
Constant_Present => True,
Object_Definition =>
New_Occurrence_Of (Standard_String, Loc),
Expression =>
Make_String_Literal (Loc,
Fully_Qualified_Name_String (First_Subtype (Typ)))));
end if;
Set_Is_Statically_Allocated (External_Tag_Name);
Set_Is_True_Constant (External_Tag_Name);
end if;
-- Declare the object used by Ada.Tags.Register_Tag -- Declare the object used by Ada.Tags.Register_Tag
...@@ -5120,8 +5062,8 @@ package body Exp_Disp is ...@@ -5120,8 +5062,8 @@ package body Exp_Disp is
-- (Idepth => I_Depth, -- (Idepth => I_Depth,
-- Access_Level => Type_Access_Level (Typ), -- Access_Level => Type_Access_Level (Typ),
-- Alignment => Typ'Alignment, -- Alignment => Typ'Alignment,
-- Expanded_Name => Cstring_Ptr!(ExpandedName'Address)) -- Expanded_Name => Cstring_Ptr!(Exname'Address))
-- External_Tag => Cstring_Ptr!(ExternalName'Address)) -- External_Tag => Cstring_Ptr!(Exname'Address))
-- HT_Link => HT_Link'Address, -- HT_Link => HT_Link'Address,
-- Transportable => <<boolean-value>>, -- Transportable => <<boolean-value>>,
-- Is_Abstract => <<boolean-value>>, -- Is_Abstract => <<boolean-value>>,
...@@ -5191,18 +5133,9 @@ package body Exp_Disp is ...@@ -5191,18 +5133,9 @@ package body Exp_Disp is
Append_To (TSD_Aggr_List, Append_To (TSD_Aggr_List,
Unchecked_Convert_To (RTE (RE_Cstring_Ptr), Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
Make_Attribute_Reference (Loc, Make_Attribute_Reference (Loc,
Prefix => New_Occurrence_Of (Expanded_Name, Loc), Prefix => New_Occurrence_Of (Exname, Loc),
Attribute_Name => Name_Address))); Attribute_Name => Name_Address)));
-- External_Tag when pragma No_Tagged_Streams applies
if Present (No_Tagged_Streams_Pragma (Typ)) then
New_Node :=
Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
Make_Attribute_Reference (Loc,
Prefix => New_Occurrence_Of (External_Tag_Name, Loc),
Attribute_Name => Name_Address));
-- External_Tag of a local tagged type -- External_Tag of a local tagged type
-- <typ>A : constant String := -- <typ>A : constant String :=
...@@ -5230,7 +5163,8 @@ package body Exp_Disp is ...@@ -5230,7 +5163,8 @@ package body Exp_Disp is
-- specified. That's an odd case for which we have already issued a -- specified. That's an odd case for which we have already issued a
-- warning, where we will not be able to compute the internal tag. -- warning, where we will not be able to compute the internal tag.
elsif not Is_Library_Level_Entity (Typ) if not Discard_Names
and then not Is_Library_Level_Entity (Typ)
and then not Has_External_Tag_Rep_Clause (Typ) and then not Has_External_Tag_Rep_Clause (Typ)
then then
declare declare
...@@ -5333,8 +5267,7 @@ package body Exp_Disp is ...@@ -5333,8 +5267,7 @@ package body Exp_Disp is
New_Node := New_Node :=
Unchecked_Convert_To (RTE (RE_Cstring_Ptr), Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
Make_Attribute_Reference (Loc, Make_Attribute_Reference (Loc,
Prefix => Prefix => New_Occurrence_Of (Exname, Loc),
New_Occurrence_Of (External_Tag_Name, Loc),
Attribute_Name => Name_Address)); Attribute_Name => Name_Address));
else else
Old_Val := Strval (Expr_Value_S (Expression (Def))); Old_Val := Strval (Expr_Value_S (Expression (Def)));
...@@ -6501,7 +6434,7 @@ package body Exp_Disp is ...@@ -6501,7 +6434,7 @@ package body Exp_Disp is
-- applies to Ada 2005 (and Ada 2012). It might be argued that it is -- applies to Ada 2005 (and Ada 2012). It might be argued that it is
-- a desirable check to add in Ada 95 mode, but we hesitate to make -- a desirable check to add in Ada 95 mode, but we hesitate to make
-- this change, as it would be incompatible, and could conceivably -- this change, as it would be incompatible, and could conceivably
-- cause a problem in existing Aa 95 code. -- cause a problem in existing Ada 95 code.
-- We check for No_Run_Time_Mode here, because we do not want to pick -- We check for No_Run_Time_Mode here, because we do not want to pick
-- up the RE_Check_TSD entity and call it in No_Run_Time mode. -- up the RE_Check_TSD entity and call it in No_Run_Time mode.
...@@ -6510,10 +6443,10 @@ package body Exp_Disp is ...@@ -6510,10 +6443,10 @@ package body Exp_Disp is
-- was discarded. -- was discarded.
if not No_Run_Time_Mode if not No_Run_Time_Mode
and then not Discard_Names
and then Ada_Version >= Ada_2005 and then Ada_Version >= Ada_2005
and then RTE_Available (RE_Check_TSD) and then RTE_Available (RE_Check_TSD)
and then not Duplicated_Tag_Checks_Suppressed (Typ) and then not Duplicated_Tag_Checks_Suppressed (Typ)
and then not (Global_Discard_Names or else Discard_Names (Typ))
then then
Append_To (Elab_Code, Append_To (Elab_Code,
Make_Procedure_Call_Statement (Loc, Make_Procedure_Call_Statement (Loc,
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
@copying @copying
@quotation @quotation
GNAT Reference Manual , Apr 20, 2018 GNAT Reference Manual , Apr 23, 2018
AdaCore AdaCore
...@@ -5328,6 +5328,11 @@ and derived types of this type inherit the pragma automatically, so the effect ...@@ -5328,6 +5328,11 @@ and derived types of this type inherit the pragma automatically, so the effect
applies to a complete hierarchy (this is necessary to deal with the class-wide applies to a complete hierarchy (this is necessary to deal with the class-wide
dispatching versions of the stream routines). dispatching versions of the stream routines).
When pragmas @code{Discard_Names} and @code{No_Tagged_Streams} are simultaneously
applied to a tagged type its Expanded_Name and External_Tag are initialized
with empty strings. This is useful to avoid exposing entity names at binary
level but has a negative impact on the debuggability of tagged types.
@node Pragma Normalize_Scalars,Pragma Obsolescent,Pragma No_Tagged_Streams,Implementation Defined Pragmas @node Pragma Normalize_Scalars,Pragma Obsolescent,Pragma No_Tagged_Streams,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-normalize-scalars}@anchor{a8} @anchor{gnat_rm/implementation_defined_pragmas pragma-normalize-scalars}@anchor{a8}
@section Pragma Normalize_Scalars @section Pragma Normalize_Scalars
...@@ -17143,6 +17148,11 @@ be suppressed. In the presence of this pragma, the Image attribute ...@@ -17143,6 +17148,11 @@ be suppressed. In the presence of this pragma, the Image attribute
provides the image of the Pos of the literal, and Value accepts provides the image of the Pos of the literal, and Value accepts
Pos values. Pos values.
For tagged types, when pragmas @code{Discard_Names} and @code{No_Tagged_Streams}
simultaneously apply, their Expanded_Name and External_Tag are initialized
with empty strings. This is useful to avoid exposing entity names at binary
level.
@itemize * @itemize *
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment