This patch avoids issuing a warning for a "missing" component clause for a discriminant in an unchecked union, and also avoids printing a line for such a component in the -gnatR2 output.
The following program: 1. with Interfaces; 2. procedure Test_Union is 3. type Test_Type (Flag : Boolean) is 4. record 5. case Flag is 6. when True => 7. Thing_1 : Interfaces.Unsigned_32; 8. when False => 9. Thing_2 : Interfaces.Unsigned_32; 10. end case; 11. end record 12. with Unchecked_Union; 13. for Test_Type use 14. record 15. Thing_1 at 0 range 0 .. 31; 16. Thing_2 at 0 range 0 .. 31; 17. end record; 18. pragma Unreferenced (Test_Type); 19. begin 20. null; 21. end Test_Union; compiles quietly with switches -gnatwa -gnatR2, and generates this representation output: Representation information for unit Test_Union (body) for Test_Type'Size use 32; for Test_Type'Alignment use 4; for Test_Type use record Thing_1 at 0 range 0 .. 31; Thing_2 at 0 range 0 .. 31; end record; Tested on x86_64-pc-linux-gnu, committed on trunk 2014-11-20 Robert Dewar <de...@adacore.com> * repinfo.adb (List_Record_Info): Do not list discriminant in unchecked union. * sem_ch13.adb (Has_Good_Profile): Minor reformatting (Analyze_Stream_TSS_Definition): Minor reformatting (Analyze_Record_Representation_Clause): Do not issue warning for missing rep clause for discriminant in unchecked union.
Index: repinfo.adb =================================================================== --- repinfo.adb (revision 217828) +++ repinfo.adb (working copy) @@ -847,37 +847,49 @@ Comp := First_Component_Or_Discriminant (Ent); while Present (Comp) loop - Get_Decoded_Name_String (Chars (Comp)); - Max_Name_Length := Natural'Max (Max_Name_Length, Name_Len); - Cfbit := Component_Bit_Offset (Comp); + -- Skip discriminant in unchecked union (since it is not there!) - if Rep_Not_Constant (Cfbit) then - UI_Image_Length := 2; + if Ekind (Comp) = E_Discriminant + and then Is_Unchecked_Union (Ent) + then + null; + -- All other cases + else - -- Complete annotation in case not done + Get_Decoded_Name_String (Chars (Comp)); + Max_Name_Length := Natural'Max (Max_Name_Length, Name_Len); - Set_Normalized_Position (Comp, Cfbit / SSU); - Set_Normalized_First_Bit (Comp, Cfbit mod SSU); + Cfbit := Component_Bit_Offset (Comp); - Sunit := Cfbit / SSU; - UI_Image (Sunit); - end if; + if Rep_Not_Constant (Cfbit) then + UI_Image_Length := 2; - -- If the record is not packed, then we know that all fields whose - -- position is not specified have a starting normalized bit position - -- of zero. + else + -- Complete annotation in case not done - if Unknown_Normalized_First_Bit (Comp) - and then not Is_Packed (Ent) - then - Set_Normalized_First_Bit (Comp, Uint_0); + Set_Normalized_Position (Comp, Cfbit / SSU); + Set_Normalized_First_Bit (Comp, Cfbit mod SSU); + + Sunit := Cfbit / SSU; + UI_Image (Sunit); + end if; + + -- If the record is not packed, then we know that all fields + -- whose position is not specified have a starting normalized + -- bit position of zero. + + if Unknown_Normalized_First_Bit (Comp) + and then not Is_Packed (Ent) + then + Set_Normalized_First_Bit (Comp, Uint_0); + end if; + + Max_Suni_Length := + Natural'Max (Max_Suni_Length, UI_Image_Length); end if; - Max_Suni_Length := - Natural'Max (Max_Suni_Length, UI_Image_Length); - Next_Component_Or_Discriminant (Comp); end loop; @@ -885,6 +897,17 @@ Comp := First_Component_Or_Discriminant (Ent); while Present (Comp) loop + + -- Skip discriminant in unchecked union (since it is not there!) + + if Ekind (Comp) = E_Discriminant + and then Is_Unchecked_Union (Ent) + then + goto Continue; + end if; + + -- All other cases + declare Esiz : constant Uint := Esize (Comp); Bofs : constant Uint := Component_Bit_Offset (Comp); Index: sem_ch13.adb =================================================================== --- sem_ch13.adb (revision 217857) +++ sem_ch13.adb (working copy) @@ -3555,7 +3555,7 @@ if Base_Type (Typ) = Base_Type (Ent) or else (Is_Class_Wide_Type (Typ) - and then Typ = Class_Wide_Type (Base_Type (Ent))) + and then Typ = Class_Wide_Type (Base_Type (Ent))) then null; else @@ -3650,8 +3650,8 @@ (Ekind (Subp) = E_Function or else not Null_Present - (Specification - (Unit_Declaration_Node (Ultimate_Alias (Subp))))) + (Specification + (Unit_Declaration_Node (Ultimate_Alias (Subp))))) then Error_Msg_N ("stream subprogram for interface type " @@ -6600,6 +6600,12 @@ or else Size_Known_At_Compile_Time (Underlying_Type (Etype (Comp)))) and then not Has_Warnings_Off (Rectype) + + -- Ignore discriminant in unchecked union, since it is + -- not there, and cannot have a component clause. + + and then (not Is_Unchecked_Union (Rectype) + or else Ekind (Comp) /= E_Discriminant) then Error_Msg_Sloc := Sloc (Comp); Error_Msg_NE