https://gcc.gnu.org/g:0362d7aa8fcdb63505a6b37a36fc7cc5845ba80c

commit r15-5154-g0362d7aa8fcdb63505a6b37a36fc7cc5845ba80c
Author: Eric Botcazou <ebotca...@adacore.com>
Date:   Mon Oct 28 11:58:55 2024 +0100

    ada: Fix assertion failure on illegal use of aspect Type_Invariant
    
    The illegal use is on a type derived from a formal private type, e.g.:
    
    generic
    
      type T is private;
    
    package G is
    
      type D is new T with Type_Invariant => True;
    
    end G;
    
    gcc/ada/ChangeLog:
    
            PR ada/113037
            * sem_prag.adb (Analyze_Pragma) <Pragma_Invariant>: Reject types
            that are derived from formal private types.

Diff:
---
 gcc/ada/sem_prag.adb | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index f4ae89fd2e7a..ef9039652321 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -19773,18 +19773,26 @@ package body Sem_Prag is
 
             --  An invariant must apply to a private type, or appear in the
             --  private part of a package spec and apply to a completion.
-            --  a class-wide invariant can only appear on a private declaration
+            --  A class-wide invariant can only appear on a private declaration
             --  or private extension, not a completion.
 
-            --  A [class-wide] invariant may be associated a [limited] private
-            --  type or a private extension.
+            --  A [class-wide] invariant may be associated with a [limited]
+            --  private type. We need to explicitly exclude types that are
+            --  derived from formal private types here.
 
             elsif Ekind (Typ) in E_Limited_Private_Type
                                | E_Private_Type
-                               | E_Record_Type_With_Private
+              and then not (Is_Derived_Type (Typ)
+                             and then Is_Generic_Type (Etype (Typ)))
             then
                null;
 
+            --  A [class-wide] invariant may be associated with a private
+            --  extension.
+
+            elsif Ekind (Typ) = E_Record_Type_With_Private then
+               null;
+
             --  A non-class-wide invariant may be associated with the full view
             --  of a [limited] private type or a private extension.

Reply via email to