]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ada: Fix assertion failure on aggregate with controlled component
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 8 Jul 2025 09:05:19 +0000 (11:05 +0200)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 22 Jul 2025 10:11:39 +0000 (12:11 +0200)
The assertion is:

      pragma Assert (Side_Effect_Free (L));

in Make_Tag_Ctrl_Assignment and demonstrates that the sequence:

  Remove_Side_Effects (L);
  pragma Assert (Side_Effect_Free (L));

does not hold in this case.

What happens is that Remove_Side_Effects uses a renaming to remove the side
effects of L but, at the end, the renamed object is substituted back for the
renamed object in the node by Expand_Renaming, which is invoked because the
Is_Renaming_Of_Object flag is set on the renaming after Evaluate_Name has
been invoked on its Name.

This is a general discrepancy between Evaluate_Name and Side_Effect_Free of
Exp_Util, coming from the call to Safe_Unchecked_Type_Conversion present in
Side_Effect_Free in this case.  The long term goal is probably to remove the
call but, in the meantime, this change is sufficient to fix the failure.

gcc/ada/ChangeLog:

* exp_util.adb (Safe_Unchecked_Type_Conversion): Always return True
if the expression is the prefix of an N_Selected_Component.

gcc/ada/exp_util.adb

index b3dbe98e02bd1375362735ab5e25cf45417e8573..cfbca9100174384602b991f68ef157bcbfe68eba 100644 (file)
@@ -13662,11 +13662,12 @@ package body Exp_Util is
    --  The above requirements should be documented in Sinfo ???
 
    function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
+      Pexp : constant Node_Id := Parent (Exp);
+
       Otyp   : Entity_Id;
       Ityp   : Entity_Id;
       Oalign : Uint;
       Ialign : Uint;
-      Pexp   : constant Node_Id := Parent (Exp);
 
    begin
       --  If the expression is the RHS of an assignment or object declaration
@@ -13684,18 +13685,12 @@ package body Exp_Util is
          return True;
 
       --  If the expression is the prefix of an N_Selected_Component we should
-      --  also be OK because GCC knows to look inside the conversion except if
-      --  the type is discriminated. We assume that we are OK anyway if the
-      --  type is not set yet or if it is controlled since we can't afford to
-      --  introduce a temporary in this case.
+      --  also be OK because GCC knows to look inside the conversion.
 
       elsif Nkind (Pexp) = N_Selected_Component
         and then Prefix (Pexp) = Exp
       then
-         return No (Etype (Pexp))
-           or else not Is_Type (Etype (Pexp))
-           or else not Has_Discriminants (Etype (Pexp))
-           or else Is_Constrained (Etype (Pexp));
+         return True;
       end if;
 
       --  Set the output type, this comes from Etype if it is set, otherwise we