diff mbox series

[Ada] Spurious error on instance with predicated actual

Message ID 20201125132724.GA116044@adacore.com
State New
Headers show
Series [Ada] Spurious error on instance with predicated actual | expand

Commit Message

Pierre-Marie de Rodat Nov. 25, 2020, 1:27 p.m. UTC
This patch removes an error on an instantiation when the actual is a
scalar type with a dynamic predicate, and its bounds are compatible
with those of the corresponding formal parameter. Section 4.9.1 of
the RM specifies that subtypes S1 and S2 can be statically compatible
even if S1 is not static, as long as all predicates of S2 also
apply to S1. In particular this applies when S2 has no predicates,
as is usually the case for generic formals.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

	* sem_eval.adb (Subtypes_Statically_Compatible): Scalar types
	with compatible static bounds are statically compatible if
	predicates are compatible, even if they are not static subtypes.
	Same for private types without discriminants.
diff mbox series

Patch

diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -6311,11 +6311,13 @@  package body Sem_Eval is
          if Subtypes_Statically_Match (T1, T2) then
             return True;
 
-         --  If either subtype is nonstatic then they're not compatible
+         --  A scalar subtype S1 is compatible with S2 if their bounds
+         --  are static and compatible, even if S1 has dynamic predicates
+         --  and is thus non-static. Predicate compatibility has been
+         --  checked above.
 
-         elsif not Is_OK_Static_Subtype (T1)
-                 or else
-               not Is_OK_Static_Subtype (T2)
+         elsif not Is_Static_Range (Scalar_Range (T1))
+                 or else not Is_Static_Range (Scalar_Range (T2))
          then
             return False;
 
@@ -6363,6 +6365,14 @@  package body Sem_Eval is
            and then not (Can_Never_Be_Null (T2)
                           and then not Can_Never_Be_Null (T1));
 
+      --  Private types without discriminants can be handled specially.
+      --  Predicate matching has been checked above.
+
+      elsif Is_Private_Type (T1)
+        and then not Has_Discriminants (T1)
+      then
+         return not Has_Discriminants (T2);
+
       --  All other cases
 
       else