[Ada] Fix crash on Unchecked_Union component with -gnateV

Eric Botcazou <[email protected]> Sat, 01 Aug 2026 18:47:39 +0200
Newsgroups gmane.comp.gcc.patches
Message-ID <5093182.GXAFRqVoOG@arcturus>
This is the same bug as PR ada/123857, but at a nested level, and the fix is 
the same 1-liner but at a different place.

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

Jakub or Richard, I'd like to backport it for the 16.2 release too, since it's 
again a trivial 1-liner that cannot break anything.  Thanks in advance.


2026-08-01  Eric Botcazou  <[email protected]>

	PR ada/126553
	* exp_attr.adb (Build_Record_VS_Func.Validate_Field): Do nothing
	if the field is of an Unchecked_Union type.


2026-08-01  Eric Botcazou  <[email protected]>

	* gnat.dg/unchecked_union5.adb: New test.

-- 
Eric Botcazou
pr126553.diff (text/x-patch, 782 B)
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 15219a73c27..6ed2de30cb8 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -781,9 +781,12 @@ package body Exp_Attr is
          if Field_Nam in Name_uObject | Name_uParent | Name_uTag then
             null;
 
-         --  Do not process fields without any scalar components
+         --  Do not process fields without any scalar components, or whose type
+         --  is an unchecked union since we cannot know where they are.
 
-         elsif not Scalar_Part_Present (Field_Typ) then
+         elsif not Scalar_Part_Present (Field_Typ)
+           or else Is_Unchecked_Union (Field_Typ)
+         then
             null;
 
          --  Otherwise the field needs to be validated. Use Make_Identifier
unchecked_union5.adb (text/x-adasrc, 432 B)
--  { dg-do compile }
--  { dg-options "-gnateV" }

procedure Unchecked_Union5 is

   type R (Bytes_Mode : Boolean := False) is record
      case Bytes_Mode is
         when True =>
            A : Boolean;
         when False =>
            B : Boolean;
      end case;
   end record with Unchecked_Union;

   type T is record
      Data : R;
   end record;

   function F (Message : T) return Integer is (0);

begin
   null;
end;