aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Schonberg <schonberg@adacore.com>2019-07-10 09:02:55 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2019-07-10 09:02:55 +0000
commit4669743bd255d2ab4ff33672e8843a914e5c1d35 (patch)
tree96e179791fdde784f987de9c6a842e0f35cd889c
parentccba4bf136ef7012e7387119a86da56575802c4f (diff)
downloadgcc-4669743bd255d2ab4ff33672e8843a914e5c1d35.zip
gcc-4669743bd255d2ab4ff33672e8843a914e5c1d35.tar.gz
gcc-4669743bd255d2ab4ff33672e8843a914e5c1d35.tar.bz2
[Ada] Spurious run-time error with 64-bit modular types
As a lexical element an integer literal has type Universal_Integer, i.e is compatible with any integer type. This is semantically consistent and simplifies type checking and subsequent constant folding when applicable. An exception is caused by 64-bit modular types, whose upper bound is not representable in a non-static context that will use 64-bit integers at run-time. For such cases we need to preserve the information that the analyzed literal has that modular type. For simplicity we preseve the information for all integer literals that result from a modular operation. This happens after prior analysis (or construction) of the literal, and after type checking and resolution. 2019-07-10 Ed Schonberg <schonberg@adacore.com> gcc/ada/ * sem_ch2.adb (Analyze_Integer_Literal): Preserve the type of the literal if prior analysis determined that its type is a modular integer type. gcc/testsuite/ * gnat.dg/modular5.adb: New testcase. From-SVN: r273352
-rw-r--r--gcc/ada/ChangeLog6
-rw-r--r--gcc/ada/sem_ch2.adb21
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/modular5.adb26
4 files changed, 56 insertions, 1 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 996dd18..94fab7f 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,9 @@
+2019-07-10 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch2.adb (Analyze_Integer_Literal): Preserve the type of
+ the literal if prior analysis determined that its type is a
+ modular integer type.
+
2019-07-10 Doug Rupp <rupp@adacore.com>
* init.c: Do not attempt to re-arm guard page on x86_64-vx7(r2).
diff --git a/gcc/ada/sem_ch2.adb b/gcc/ada/sem_ch2.adb
index 3b46ad5..0a282d4 100644
--- a/gcc/ada/sem_ch2.adb
+++ b/gcc/ada/sem_ch2.adb
@@ -24,12 +24,14 @@
------------------------------------------------------------------------------
with Atree; use Atree;
+with Einfo; use Einfo;
with Namet; use Namet;
with Opt; use Opt;
with Restrict; use Restrict;
with Rident; use Rident;
with Sem_Ch8; use Sem_Ch8;
with Sem_Dim; use Sem_Dim;
+-- with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
with Stand; use Stand;
with Uintp; use Uintp;
@@ -83,7 +85,24 @@ package body Sem_Ch2 is
procedure Analyze_Integer_Literal (N : Node_Id) is
begin
- Set_Etype (N, Universal_Integer);
+ -- As a lexical element, an integer literal has type Universal_Integer,
+ -- i.e., is compatible with any integer type. This is semantically
+ -- consistent and simplifies type checking and subsequent constant
+ -- folding when needed. An exception is caused by 64-bit modular types,
+ -- whose upper bound is not representable in a nonstatic context that
+ -- will use 64-bit integers at run time. For such cases, we need to
+ -- preserve the information that the analyzed literal has that modular
+ -- type. For simplicity, we preserve the information for all integer
+ -- literals that result from a modular operation. This happens after
+ -- prior analysis (or construction) of the literal, and after type
+ -- checking and resolution.
+
+ if No (Etype (N))
+ or else not Is_Modular_Integer_Type (Etype (N))
+ then
+ Set_Etype (N, Universal_Integer);
+ end if;
+
Set_Is_Static_Expression (N);
end Analyze_Integer_Literal;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e2dc5fe..a953397 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2019-07-10 Ed Schonberg <schonberg@adacore.com>
+ * gnat.dg/modular5.adb: New testcase.
+
+2019-07-10 Ed Schonberg <schonberg@adacore.com>
+
* gnat.dg/limited3.adb, gnat.dg/limited3_pkg.adb,
gnat.dg/limited3_pkg.ads: New testcase.
diff --git a/gcc/testsuite/gnat.dg/modular5.adb b/gcc/testsuite/gnat.dg/modular5.adb
new file mode 100644
index 0000000..7fcf59c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/modular5.adb
@@ -0,0 +1,26 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+procedure Modular5 is
+ type U64 is mod 2 ** 64;
+ Maybe : Boolean := 2 ** 10 < U64'Succ (U64'last - 1);
+ For_Sure : Boolean := U64'(18446744073709551615) > 2;
+ Ditto : Boolean := 18446744073709551615 > 2;
+
+ generic
+ type TG is mod <>;
+ package PG is
+ X : TG;
+ pragma Assert (for all K in 1 .. 2 => 2 ** K <= TG'Last);
+ pragma Assert (for all K in 1 .. 2 => 2 ** K <= TG'Last - 1);
+
+ Maybe : Boolean := 2 ** 10 < TG'Succ (TG'last - 1);
+ For_Sure : Boolean := TG'(18446744073709551615) > 2;
+ end PG;
+
+ package IG is new PG (U64);
+
+begin
+ pragma Assert (for all K in 1 .. 2 => 2 ** K <= U64'Last);
+ pragma Assert (for all K in 1 .. 2 => 2 ** K <= U64'Last - 1);
+end Modular5;