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

login
register
mail settings
Submitter Arnaud Charlet
Date June 12, 2012, 10:09 a.m.
Message ID <20120612100907.GA10781@adacore.com>
Download mbox | patch
Permalink /patch/164367/
State New
Headers show

Comments

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

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);