From: Mathias Aparicio <[email protected]>

Before this patch, Case_Expression inside a Pragma_Predicate with a
non-static alternative (like a function call) led the Case_Expression
Node to survive unexpanded and caused gnat_to_gnu to abort
(gcc_unreachable for N_Case_Expression).

The guard in Expand_N_Case_Expression checking for non-static
Predicate_Aspect used Has_Dynamic_Predicate_Aspect, which was false
even with a function call in a Case_Expression alternative.

Now add Is_Predicate_Static to the check, which fixes the bug.
This function was private to the sem_ch13 package, so it was made public.

gcc/ada/ChangeLog:

        * sem_ch13.ads (Is_Predicate_Static): Public declaration,
        from the private function in the package body
        * sem_ch13.adb (Is_Predicate_Static): Remove the now-redundant
        local declaration
        * exp_ch4.adb (Expand_N_Case_Expression): Add Is_Predicate_Static
        to the static guard

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_ch4.adb  |  4 +++-
 gcc/ada/sem_ch13.adb | 35 -----------------------------------
 gcc/ada/sem_ch13.ads | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index e8eaa7556b7..f3db82c3e72 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -5291,7 +5291,7 @@ package body Exp_Ch4 is
 
       --  If the case expression is a predicate specification, do not expand
       --  because it will need to be recognized and converted to the canonical
-      --  predicate form later if it it happens to be static.
+      --  predicate form later if it happens to be static.
 
       if Ekind (Scop) in E_Function | E_Procedure
         and then Is_Predicate_Function (Scop)
@@ -5299,6 +5299,8 @@ package body Exp_Ch4 is
         and then Entity (Expression (N)) = First_Entity (Scop)
         and then (Is_Scalar_Type (Etype (Expression (N)))
                    or else Is_String_Type (Etype (Expression (N))))
+        and then Is_Predicate_Static
+            (Expr => N, Nam => Chars (First_Entity (Scop)), Warn => False)
         and then not Has_Dynamic_Predicate_Aspect (Etype (Expression (N)))
       then
          return;
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index d84e8aeb29f..3de75356d4e 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -45,7 +45,6 @@ with Ghost;            use Ghost;
 with Lib;              use Lib;
 with Lib.Xref;         use Lib.Xref;
 with Mutably_Tagged;   use Mutably_Tagged;
-with Namet;            use Namet;
 with Nlists;           use Nlists;
 with Nmake;            use Nmake;
 with Opt;              use Opt;
@@ -235,40 +234,6 @@ package body Sem_Ch13 is
    --  Returns True for a representation clause/pragma that specifies a
    --  type-related representation (as opposed to operational) aspect.
 
-   function Is_Predicate_Static
-     (Expr : Node_Id;
-      Nam  : Name_Id;
-      Warn : Boolean := True) return Boolean;
-   --  Given predicate expression Expr, tests if Expr is predicate-static in
-   --  the sense of the rules in (RM 3.2.4 (15-24)). Occurrences of the type
-   --  name in the predicate expression have been replaced by references to
-   --  an identifier whose Chars field is Nam. This name is unique, so any
-   --  identifier with Chars matching Nam must be a reference to the type.
-   --  Returns True if the expression is predicate-static and False otherwise,
-   --  but is not in the business of setting flags or issuing error messages.
-   --
-   --  Only scalar types can have static predicates, so False is always
-   --  returned for non-scalar types.
-   --
-   --  Note: the RM seems to suggest that string types can also have static
-   --  predicates. But that really makes little sense as very few useful
-   --  predicates can be constructed for strings. Remember that:
-   --
-   --     "ABC" < "DEF"
-   --
-   --  is not a static expression. So even though the clearly faulty RM wording
-   --  allows the following:
-   --
-   --     subtype S is String with Static_Predicate => S < "DEF"
-   --
-   --  We can't allow this, otherwise we have predicate-static applying to a
-   --  larger class than static expressions, which was never intended.
-   --
-   --  The Warn parameter is True iff this is not a recursive call. This
-   --  parameter is used to avoid generating warnings for subexpressions and
-   --  for cases where the predicate expression (as originally written by
-   --  the user, before any transformations) is a Boolean literal.
-
    procedure New_Put_Image_Subprogram
      (N    : Node_Id;
       Ent  : Entity_Id;
diff --git a/gcc/ada/sem_ch13.ads b/gcc/ada/sem_ch13.ads
index ca9dbf9f841..0b31c9e15d6 100644
--- a/gcc/ada/sem_ch13.ads
+++ b/gcc/ada/sem_ch13.ads
@@ -28,6 +28,7 @@ with Types; use Types;
 with Sem_Disp; use Sem_Disp;
 with Sinfo.Nodes; use Sinfo.Nodes;
 with Uintp; use Uintp;
+with Namet; use Namet;
 
 package Sem_Ch13 is
    function All_Membership_Choices_Static (Expr : Node_Id) return Boolean;
@@ -386,4 +387,36 @@ package Sem_Ch13 is
    procedure Uninstall_Discriminants (E : Entity_Id);
    --  Remove visibility to the discriminants of type entity E
 
+   function Is_Predicate_Static
+     (Expr : Node_Id; Nam : Name_Id; Warn : Boolean := True) return Boolean;
+   --  Given predicate expression Expr, tests if Expr is predicate-static in
+   --  the sense of the rules in (RM 3.2.4 (15-24)). Occurrences of the type
+   --  name in the predicate expression have been replaced by references to
+   --  an identifier whose Chars field is Nam. This name is unique, so any
+   --  identifier with Chars matching Nam must be a reference to the type.
+   --  Returns True if the expression is predicate-static and False otherwise,
+   --  but is not in the business of setting flags or issuing error messages.
+   --
+   --  Only scalar types can have static predicates, so False is always
+   --  returned for non-scalar types.
+   --
+   --  Note: the RM seems to suggest that string types can also have static
+   --  predicates. But that really makes little sense as very few useful
+   --  predicates can be constructed for strings. Remember that:
+   --
+   --     "ABC" < "DEF"
+   --
+   --  is not a static expression. So even though the clearly faulty RM wording
+   --  allows the following:
+   --
+   --     subtype S is String with Static_Predicate => S < "DEF"
+   --
+   --  We can't allow this, otherwise we have predicate-static applying to a
+   --  larger class than static expressions, which was never intended.
+   --
+   --  The Warn parameter is True iff this is not a recursive call. This
+   --  parameter is used to avoid generating warnings for subexpressions and
+   --  for cases where the predicate expression (as originally written by
+   --  the user, before any transformations) is a Boolean literal.
+
 end Sem_Ch13;
-- 
2.53.0

Reply via email to