aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Duff <duff@adacore.com>2016-07-06 12:32:35 +0000
committerArnaud Charlet <charlet@gcc.gnu.org>2016-07-06 14:32:35 +0200
commit1956beb8aa91181d614441e943a76fa7f7d8d51c (patch)
treeab3dafd3172a46b0fe10aff675670eb0e1ee1947
parent7b4e076985f2c41f93fb8d8f89183ef1244f98ae (diff)
downloadgcc-1956beb8aa91181d614441e943a76fa7f7d8d51c.zip
gcc-1956beb8aa91181d614441e943a76fa7f7d8d51c.tar.gz
gcc-1956beb8aa91181d614441e943a76fa7f7d8d51c.tar.bz2
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
-rw-r--r--gcc/ada/ChangeLog8
-rw-r--r--gcc/ada/exp_attr.adb57
-rw-r--r--gcc/ada/sem_attr.adb12
3 files changed, 42 insertions, 35 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 9ddf035..9a16f81 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,11 @@
+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
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 6c5f3b5..47cee2b 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -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);
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index d6d8509..a05ad7e 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -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);