The problem is that the compiler generates 'Valid_Scalars for a formal
parameter of an Unchecked_Union type, which cannot work because it is not
possible to find out where the scalars are in it, given that the parameter
does not contain the discriminants of its Unchecked_Union type. This also
changes -gnateV to work without the need for -gnata, as there is no mention of
this dependence in the documentation.
Tested on x86-64/Linux, applied on the mainline and 15 branch.
2026-01-28 Eric Botcazou <[email protected]>
PR ada/123857
* checks.adb (Apply_Parameter_Validity_Checks.Add_Validity_Check):
Set Is_Checked on the generated {Pre,Post}_Condition pragma and
bail out if the parameter is of an Unchecked_Union type.
2026-01-28 Eric Botcazou <[email protected]>
* gnat.dg/unchecked_union4.adb: New test.
--
Eric Botcazoudiff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index 4d147d02036..55a81d90045 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -2584,6 +2584,10 @@ package body Checks is
Chars => Name_Check,
Expression => Expr)));
+ -- The check is enabled unconditionally
+
+ Set_Is_Checked (Prag);
+
-- Add a message unless exception messages are suppressed
if not Exception_Locations_Suppressed then
@@ -2641,9 +2645,12 @@ package body Checks is
if Is_Scalar_Type (Typ) then
Nam := Name_Valid;
- -- For any non-scalar with scalar parts, generate 'Valid_Scalars test
+ -- For non-scalars with scalar parts, generate 'Valid_Scalars test,
+ -- except for unchecked unions since we cannot know where they are.
- elsif Scalar_Part_Present (Typ) then
+ elsif Scalar_Part_Present (Typ)
+ and then not Is_Unchecked_Union (Typ)
+ then
Nam := Name_Valid_Scalars;
-- No test needed for other cases (no scalars to test)
@@ -2735,8 +2742,7 @@ package body Checks is
return;
end if;
- -- Inspect all the formals applying aliasing and scalar initialization
- -- checks where applicable.
+ -- Apply scalar initialization checks to formals where applicable
Formal := First_Formal (Subp);
while Present (Formal) loop
-- { dg-do compile }
-- { dg-options "-gnateV" }
procedure Unchecked_Union4 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;
function F (Message : R) return Integer is (0);
begin
null;
end;