summaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2017-01-23 11:19:56 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2017-01-23 11:19:56 +0000
commit5f2dd1720c47842fd08ee9cce26980a1c7dcccd6 (patch)
treedb41c8e1c5a062bf3dd5dd48a8dbfcba6f173090 /gcc/ada
parentf2451eab68a5a9c646719cb7784c2ab97a2324c3 (diff)
downloadgcc-5f2dd1720c47842fd08ee9cce26980a1c7dcccd6.tar.gz
2017-01-23 Claire Dross <dross@adacore.com>
* exp_spark.adb (Expand_SPARK_Attribute_Reference): For attributes which return Universal_Integer, force the overflow check flag for Length and Range_Length for types as big as Long_Long_Integer. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@244777 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog6
-rw-r--r--gcc/ada/exp_spark.adb52
2 files changed, 57 insertions, 1 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index c2780aeeeb7..cc26c9f3793 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,11 @@
2017-01-23 Claire Dross <dross@adacore.com>
+ * exp_spark.adb (Expand_SPARK_Attribute_Reference): For attributes
+ which return Universal_Integer, force the overflow check flag for
+ Length and Range_Length for types as big as Long_Long_Integer.
+
+2017-01-23 Claire Dross <dross@adacore.com>
+
* exp_spark.adb (Expand_SPARK_Attribute_Reference): For
attributes which return Universal_Integer, introduce a conversion
to the expected type with the appropriate check flags set.
diff --git a/gcc/ada/exp_spark.adb b/gcc/ada/exp_spark.adb
index 9861c625f4b..e93f71dad05 100644
--- a/gcc/ada/exp_spark.adb
+++ b/gcc/ada/exp_spark.adb
@@ -38,6 +38,9 @@ with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
with Snames; use Snames;
with Tbuild; use Tbuild;
+with Uintp; use Uintp;
+with Sem_Eval; use Sem_Eval;
+with Stand; use Stand;
package body Exp_SPARK is
@@ -171,7 +174,54 @@ package body Exp_SPARK is
or else Attr_Id = Attribute_Aft
or else Attr_Id = Attribute_Max_Alignment_For_Allocation
then
- Apply_Universal_Integer_Attribute_Checks (N);
+
+ -- If the expected type is Long_Long_Integer, there will be no check
+ -- flag as the compiler assumes attributes always fit in this type.
+ -- Since in SPARK_Mode we do not take Storage_Error into account, we
+ -- cannot make this assumption and need to produce a check.
+ -- ??? It should be enough to add this check for attributes 'Length
+ -- and 'Range_Length when the type is as big as Long_Long_Integer.
+
+ declare
+ Typ : Entity_Id := Empty;
+ begin
+ if Attr_Id = Attribute_Range_Length then
+ Typ := Etype (Prefix (N));
+ elsif Attr_Id = Attribute_Length then
+ Typ := Etype (Prefix (N));
+
+ declare
+ Indx : Node_Id;
+ J : Int;
+ begin
+ if Is_Access_Type (Typ) then
+ Typ := Designated_Type (Typ);
+ end if;
+
+ if No (Expressions (N)) then
+ J := 1;
+ else
+ J := UI_To_Int (Expr_Value (First (Expressions (N))));
+ end if;
+
+ Indx := First_Index (Typ);
+ while J > 1 loop
+ Next_Index (Indx);
+ J := J - 1;
+ end loop;
+
+ Typ := Etype (Indx);
+ end;
+ end if;
+
+ Apply_Universal_Integer_Attribute_Checks (N);
+
+ if Present (Typ)
+ and then RM_Size (Typ) = RM_Size (Standard_Long_Long_Integer)
+ then
+ Set_Do_Overflow_Check (N);
+ end if;
+ end;
end if;
end Expand_SPARK_Attribute_Reference;