The front-end uses a trick to accept a pragma Atomic on objects whose type
isn't directly suitable for the pragma: if the type is declared in the same
unit as the object, the front-end propagates under the hood the atomicity
from the object to the type.
This can have unwanted effects, most notably if the type is elementary, the
object a simple component within a record, and both are in a spec: every
object of this type in the entire program will be treated as atomic, thus
incurring a potentially costly synchronization operation for every access.
The change restricts the propagation to composite types.
Tested on x86_64-pc-linux-gnu, committed on trunk
2012-05-15 Eric Botcazou ebotca...@adacore.com
* sem_prag.adb (Process_Atomic_Shared_Volatile): Propagate
atomicity from an object to its underlying type only if it
is composite.
Index: sem_prag.adb
===
--- sem_prag.adb(revision 187523)
+++ sem_prag.adb(working copy)
@@ -3022,16 +3022,29 @@
Set_Has_Delayed_Freeze (E);
end if;
- -- An interesting improvement here. If an object of type X is
- -- declared atomic, and the type X is not atomic, that's a
+ -- An interesting improvement here. If an object of composite
+ -- type X is declared atomic, and the type X isn't, that's a
-- pity, since it may not have appropriate alignment etc. We
-- can rescue this in the special case where the object and
-- type are in the same unit by just setting the type as
-- atomic, so that the back end will process it as atomic.
+ -- Note: we used to do this for elementary types as well,
+ -- but that turns out to be a bad idea and can have unwanted
+ -- effects, most notably if the type is elementary, the object
+ -- a simple component within a record, and both are in a spec:
+ -- every object of this type in the entire program will be
+ -- treated as atomic, thus incurring a potentially costly
+ -- synchronization operation for every access.
+
+ -- Of course it would be best if the back end could just adjust
+ -- the alignment etc for the specific object, but that's not
+ -- something we are capable of doing at this point.
+
Utyp := Underlying_Type (Etype (E));
if Present (Utyp)
+ and then Is_Composite_Type (Utyp)
and then Sloc (E) No_Location
and then Sloc (Utyp) No_Location
and then