This patch implements a new lock-free restriction. Thus, implicit dereferences of access values prevent, as well as explicit dereference, the lock-free implementation of protected objects.
The test below illustrates the new lock-free restriction: ------------ -- Source -- ------------ generic type Elmt_Type is private; type Elmt_Access is access Elmt_Type; package Test is type Node_Type; type Node_Access is access all Node_Type; type Node_Type is limited record Elmt : Elmt_Access; Prev : Node_Access; end record; protected List with Lock_Free is procedure Swap (L, R : Node_Access); private L : Node_Access := null; end List; end Test; package body Test is protected body List is ---------- -- Swap -- ---------- procedure Swap (L, R : Node_Access) is LP : constant Node_Access := L.Prev; RP : constant Node_Access := R.Prev; begin L.Prev := RP; R.Prev := LP; end Swap; end List; end Test; ----------------- -- Compilation -- ----------------- $ gnatmake -q -gnat12 test.adb test.adb:7:07: illegal body when Lock_Free given test.adb:8:40: dereference of access value not allowed test.adb:9:40: dereference of access value not allowed test.adb:12:11: dereference of access value not allowed test.adb:13:11: dereference of access value not allowed Tested on x86_64-pc-linux-gnu, committed on trunk 2012-07-30 Vincent Pucci <pu...@adacore.com> * sem_ch9.adb (Allows_Lock_Free_Implementation): Restrict implicit dereferences of access values.
Index: sem_ch9.adb =================================================================== --- sem_ch9.adb (revision 189974) +++ sem_ch9.adb (working copy) @@ -411,12 +411,15 @@ return Abandon; - -- Explicit dereferences restricted (i.e. dereferences of - -- access values). + -- Dereferences of access values restricted - elsif Kind = N_Explicit_Dereference then + elsif Kind = N_Explicit_Dereference + or else (Kind = N_Selected_Component + and then Is_Access_Type (Etype (Prefix (N)))) + then if Lock_Free_Given then - Error_Msg_N ("explicit dereference not allowed", N); + Error_Msg_N ("dereference of access value " & + "not allowed", N); return Skip; end if;