summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-15 09:57:47 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-15 09:57:47 +0000
commit46f942b1635d1d2b5828d204c914e86d58d52082 (patch)
tree71361ae103915a536a466c140fbb0b0baa9c0e6d
parent555c63a669bf0ad0343938c048251c4cb11d7b80 (diff)
downloadgcc-46f942b1635d1d2b5828d204c914e86d58d52082.tar.gz
2009-04-15 Ed Schonberg <schonberg@adacore.com>
* sem_ch4.adb: improve error message on exponentiation. 2009-04-15 Hristian Kirtchev <kirtchev@adacore.com> * a-calend.adb: Move constant Epoch_Offset from package Conversion_Operations to top level. (Delay_Operations.To_Duration): Define a constant which represents "end of time" and use it as a guard against very distant delay dates. Protect the code against overflow when performing the origin shift to Unix time. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146095 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ada/ChangeLog13
-rw-r--r--gcc/ada/a-calend.adb35
-rw-r--r--gcc/ada/sem_ch4.adb14
3 files changed, 52 insertions, 10 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 0d4a01e24eb..b56f38f0a52 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,16 @@
+2009-04-15 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch4.adb: improve error message on exponentiation.
+
+2009-04-15 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * a-calend.adb: Move constant Epoch_Offset from package
+ Conversion_Operations to top level.
+ (Delay_Operations.To_Duration): Define a constant which represents
+ "end of time" and use it as a guard against very distant delay dates.
+ Protect the code against overflow when performing the origin shift to
+ Unix time.
+
2009-04-15 Robert Dewar <dewar@adacore.com>
* sem_prag.adb: Minor reformatting.
diff --git a/gcc/ada/a-calend.adb b/gcc/ada/a-calend.adb
index 67942a8ecd2..a2759b53a89 100644
--- a/gcc/ada/a-calend.adb
+++ b/gcc/ada/a-calend.adb
@@ -177,6 +177,10 @@ package body Ada.Calendar is
Unix_Min : constant Time_Rep :=
Ada_Low + Time_Rep (17 * 366 + 52 * 365) * Nanos_In_Day;
+ Epoch_Offset : constant Time_Rep := (136 * 365 + 44 * 366) * Nanos_In_Day;
+ -- The difference between 2150-1-1 UTC and 1970-1-1 UTC expressed in
+ -- nanoseconds. Note that year 2100 is non-leap.
+
Cumulative_Days_Before_Month :
constant array (Month_Number) of Natural :=
(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334);
@@ -765,11 +769,6 @@ package body Ada.Calendar is
package body Conversion_Operations is
- Epoch_Offset : constant Time_Rep :=
- (136 * 365 + 44 * 366) * Nanos_In_Day;
- -- The difference between 2150-1-1 UTC and 1970-1-1 UTC expressed in
- -- nanoseconds. Note that year 2100 is non-leap.
-
-----------------
-- To_Ada_Time --
-----------------
@@ -972,6 +971,15 @@ package body Ada.Calendar is
-----------------
function To_Duration (Date : Time) return Duration is
+ pragma Unsuppress (Overflow_Check);
+
+ Safe_Ada_High : constant Time_Rep := Ada_High - Epoch_Offset;
+ -- This value represents a "safe" end of time. In order to perform a
+ -- proper conversion to Unix duration, we will have to shift origins
+ -- at one point. For very distant dates, this means an overflow check
+ -- failure. To prevent this, the function returns the "safe" end of
+ -- time (roughly 2219) which is still distant enough.
+
Elapsed_Leaps : Natural;
Next_Leap_N : Time_Rep;
Res_N : Time_Rep;
@@ -979,8 +987,8 @@ package body Ada.Calendar is
begin
Res_N := Time_Rep (Date);
- -- If the target supports leap seconds, remove any leap seconds
- -- elapsed up to the input date.
+ -- Step 1: If the target supports leap seconds, remove any leap
+ -- seconds elapsed up to the input date.
if Leap_Support then
Cumulative_Leap_Seconds
@@ -1000,10 +1008,17 @@ package body Ada.Calendar is
Res_N := Res_N - Time_Rep (Elapsed_Leaps) * Nano;
- -- Perform a shift in origins, note that enforcing type Time on
- -- both operands will invoke Ada.Calendar."-".
+ -- Step 2: Perform a shift in origins to obtain a Unix equivalent of
+ -- the input. Guard against very large delay values such as the end
+ -- of time since the computation will overflow.
+
+ if Res_N > Safe_Ada_High then
+ Res_N := Safe_Ada_High;
+ else
+ Res_N := Res_N + Epoch_Offset;
+ end if;
- return Time (Res_N) - Time (Unix_Min);
+ return Time_Rep_To_Duration (Res_N);
end To_Duration;
end Delay_Operations;
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index e8199b5efeb..e9a20c5a70d 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -5213,6 +5213,20 @@ package body Sem_Ch4 is
Error_Msg_N ("access parameter is not allowed to be null", L);
Error_Msg_N ("\(call would raise Constraint_Error)", L);
return;
+
+ -- Another special case for exponentiation, where the right
+ -- operand must be Natural, independently of the base.
+
+ elsif Nkind (N) = N_Op_Expon
+ and then Is_Numeric_Type (Etype (L))
+ and then not Is_Overloaded (R)
+ and then
+ First_Subtype (Base_Type (Etype (R))) /= Standard_Integer
+ and then Base_Type (Etype (R)) /= Universal_Integer
+ then
+ Error_Msg_NE
+ ("exponent must be of type Natural, found}", R, Etype (R));
+ return;
end if;
-- If we fall through then just give general message. Note that in