[Ada] Handling of (illegal) null record unchecked union

Submitted by Arnaud Charlet on June 12, 2012, 10:09 a.m.

Details

Message ID 20120612100907.GA10781@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet June 12, 2012, 10:09 a.m.
A "null record" type does not have a variant part, so it is not a legal
candidate for pragma Unchecked_Union. This change fixes the circuitry
that enforces this rule so that it correctly rejects such illegal code
instead of crashing the compiler.

The following compilation must be rejected with the indicated error message:
$ gcc -c uu_crash_null.ads
uu_crash_null.ads:2:43: Unchecked_Union must have variant part

package UU_Crash_Null is
   type UncU (Disc : Boolean := False) is null record;
   pragma Unchecked_Union (UncU);
end UU_Crash_Null;

Tested on x86_64-pc-linux-gnu, committed on trunk

2012-06-12  Thomas Quinot  <quinot@adacore.com>

	* sem_prag.adb (Analyze_Pragma, case Unchecked_Union): Do
	not crash on illegal unchecked union that is a null record.

Patch hide | download patch | download mbox

Index: sem_prag.adb
===================================================================
--- sem_prag.adb	(revision 188436)
+++ sem_prag.adb	(working copy)
@@ -14186,18 +14186,23 @@ 
                Tdef  := Type_Definition (Declaration_Node (Typ));
                Clist := Component_List (Tdef);
 
+               --  Check presence of component list and variant part
+
+               if No (Clist) or else No (Variant_Part (Clist)) then
+                  Error_Msg_N
+                    ("Unchecked_Union must have variant part", Tdef);
+                  return;
+               end if;
+
+               --  Check components
+
                Comp := First (Component_Items (Clist));
                while Present (Comp) loop
                   Check_Component (Comp, Typ);
                   Next (Comp);
                end loop;
 
-               if No (Clist) or else No (Variant_Part (Clist)) then
-                  Error_Msg_N
-                    ("Unchecked_Union must have variant part",
-                     Tdef);
-                  return;
-               end if;
+               --  Check variant part
 
                Vpart := Variant_Part (Clist);