This was reported a long time ago and is a fairly pathological case, so the 
fix is purposely ad hoc: when the attribute name of a pragma Machine_Attribute 
is not a string literal, its processing needs to be delayed for the back-end.

Tested on x86-64/Linux, applied on the mainline.


2025-10-26  Eric Botcazou  <[email protected]>

        PR ada/13370
        * sem_prag.adb (Analyze_Pragma) <Pragma_Machine_Attribute>: Set the
        Has_Delayed_Freeze flag if the argument is not a literal.


2025-10-26  Eric Botcazou  <[email protected]>

        * gnat.dg/machine_attr3.ads, gnat.dg/machine_attr3.adb: New test.

-- 
Eric Botcazou
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 28c5f1776db..6b38de037bf 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -21867,8 +21867,17 @@ package body Sem_Prag is
 
             if Rep_Item_Too_Late (Def_Id, N) then
                return;
-            else
-               Set_Has_Gigi_Rep_Item (Def_Id);
+            end if;
+
+            Set_Has_Gigi_Rep_Item (Def_Id);
+
+            --  The pragma is processed directly by the back end when Def_Id is
+            --  translated. If the argument is not a string literal, it may be
+            --  declared after Def_Id and before the pragma, which requires the
+            --  processing of Def_Id to be delayed for the back end.
+
+            if Nkind (Get_Pragma_Arg (Arg2)) /= N_String_Literal then
+               Set_Has_Delayed_Freeze (Def_Id);
             end if;
          end Machine_Attribute;
 
package Machine_Attr3 is

  procedure Proc;

private

  Attr : constant String := "nothrow";
  pragma Machine_Attribute (Proc, Attr);

end Machine_Attr3;
-- { dg-do compile }

package body Machine_Attr3 is

  procedure Proc is null;

end Machine_Attr3;

Reply via email to