diff options
author | Ed Schonberg <schonberg@adacore.com> | 2019-07-10 09:02:55 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2019-07-10 09:02:55 +0000 |
commit | 4669743bd255d2ab4ff33672e8843a914e5c1d35 (patch) | |
tree | 96e179791fdde784f987de9c6a842e0f35cd889c | |
parent | ccba4bf136ef7012e7387119a86da56575802c4f (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/ada/sem_ch2.adb | 21 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/modular5.adb | 26 |
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; |