Commit 1956beb8 by Bob Duff Committed by Arnaud Charlet

sem_attr.adb (Analyze_Attribute): Allow any expression of discrete type.

2016-07-06  Bob Duff  <duff@adacore.com>

	* sem_attr.adb (Analyze_Attribute): Allow any expression of
	discrete type.
	* exp_attr.adb (Expand_N_Attribute_Reference): Change the
	constant-folding code to correctly handle cases newly allowed
	by Analyze_Attribute.

From-SVN: r238042
parent 7b4e0769
2016-07-06 Bob Duff <duff@adacore.com>
* sem_attr.adb (Analyze_Attribute): Allow any expression of
discrete type.
* exp_attr.adb (Expand_N_Attribute_Reference): Change the
constant-folding code to correctly handle cases newly allowed
by Analyze_Attribute.
2016-07-05 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity): Invoke global_bindings_p
......
......@@ -3007,50 +3007,57 @@ package body Exp_Attr is
-- Enum_Rep --
--------------
when Attribute_Enum_Rep => Enum_Rep :
when Attribute_Enum_Rep => Enum_Rep : declare
Expr : Node_Id;
begin
-- X'Enum_Rep (Y) expands to
-- target-type (Y)
-- This is simply a direct conversion from the enumeration type to
-- the target integer type, which is treated by the back end as a
-- normal integer conversion, treating the enumeration type as an
-- integer, which is exactly what we want. We set Conversion_OK to
-- make sure that the analyzer does not complain about what otherwise
-- might be an illegal conversion.
-- Get the expression, which is X for Enum_Type'Enum_Rep (X)
-- or X'Enum_Rep.
if Is_Non_Empty_List (Exprs) then
Rewrite (N,
OK_Convert_To (Typ, Relocate_Node (First (Exprs))));
Expr := First (Exprs);
else
Expr := Pref;
end if;
-- X'Enum_Rep where X is an enumeration literal is replaced by
-- the literal value.
-- If the expression is an enumeration literal, it is
-- replaced by the literal value.
elsif Ekind (Entity (Pref)) = E_Enumeration_Literal then
if Nkind (Expr) in N_Has_Entity
and then Ekind (Entity (Expr)) = E_Enumeration_Literal
then
Rewrite (N,
Make_Integer_Literal (Loc, Enumeration_Rep (Entity (Pref))));
Make_Integer_Literal (Loc, Enumeration_Rep (Entity (Expr))));
-- If this is a renaming of a literal, recover the representation
-- of the original. If it renames an expression there is nothing
-- to fold.
elsif Ekind (Entity (Pref)) = E_Constant
and then Present (Renamed_Object (Entity (Pref)))
and then Is_Entity_Name (Renamed_Object (Entity (Pref)))
and then Ekind (Entity (Renamed_Object (Entity (Pref)))) =
elsif Nkind (Expr) in N_Has_Entity
and then Ekind (Entity (Expr)) = E_Constant
and then Present (Renamed_Object (Entity (Expr)))
and then Is_Entity_Name (Renamed_Object (Entity (Expr)))
and then Ekind (Entity (Renamed_Object (Entity (Expr)))) =
E_Enumeration_Literal
then
Rewrite (N,
Make_Integer_Literal (Loc,
Enumeration_Rep (Entity (Renamed_Object (Entity (Pref))))));
Enumeration_Rep (Entity (Renamed_Object (Entity (Expr))))));
-- If not constant-folded above, Enum_Type'Enum_Rep (X) or
-- X'Enum_Rep expands to
-- X'Enum_Rep where X is an object does a direct unchecked conversion
-- of the object value, as described for the type case above.
-- target-type (X)
-- This is simply a direct conversion from the enumeration type to
-- the target integer type, which is treated by the back end as a
-- normal integer conversion, treating the enumeration type as an
-- integer, which is exactly what we want. We set Conversion_OK to
-- make sure that the analyzer does not complain about what otherwise
-- might be an illegal conversion.
else
Rewrite (N,
OK_Convert_To (Typ, Relocate_Node (Pref)));
OK_Convert_To (Typ, Relocate_Node (Expr)));
end if;
Set_Etype (N, Typ);
......
......@@ -3742,16 +3742,8 @@ package body Sem_Attr is
Check_E1;
Check_Discrete_Type;
Resolve (E1, P_Base_Type);
else
if not Is_Entity_Name (P)
or else (not Is_Object (Entity (P))
and then Ekind (Entity (P)) /= E_Enumeration_Literal)
then
Error_Attr_P
("prefix of % attribute must be " &
"discrete type/object or enum literal");
end if;
elsif not Is_Discrete_Type (Etype (P)) then
Error_Attr_P ("prefix of % attribute must be of discrete type");
end if;
Set_Etype (N, Universal_Integer);
......
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