This is a feature request that I want to get comments on before I implement a proof-of-concept. If there is a better place for proposals rather than the main GCC list then please let me know.
Currently the internal representation for an access-to-protected-subprogram type contains two addresses: One that points at the protected object and one that points at the subprogram which takes the protected object as a parameter. The problem with this is that it prevents the Atomic aspect from being applied to access-to-protected-subprogram types on most platforms as atomic access is generally limited to the size of a single address. This proposal here is to add a new Build_Atomic_Trampolines aspect which may be applied to subprograms of protected types. When this aspect is applied to a protected subprogram, all objects of that protected type will contain a record which mirrors an access-to-protected-subprogram type, i.e. it contains the address of the object and the address of the protected procedure. These records can then be pointed to by an access-to-protected-subprogram type with a `Size => Standard'Address_Size` aspect. Such access types are only allowed to point to procedures with atomic trampolines and not any other protected subprograms, attempting otherwise will raise a Program_Error. The primary purpose of this change is to prevent the possible memory corruption detailed in PR ada/124225 without making any changes to the locking patterns. This still leaves a hole where a fallback handler may be missed if the user is moving the fallback handler between levels while a fallback handler is being resolved. However, it prevents the risk of memory corruption caused by calling a protected procedure with an invalid protected object. There are also likely other places where this will be a useful option to have. To make this seamless for users, the Build_Atomic_Trampolines aspect should be automatically applied to all procedures which match the exception handler type signature. The aspect could also be removed and atomic trampolines could be unconditionally built for all protected subprograms, this would however bloat the size of protected objects. It is also worth considering not using the Size aspect for the special access types described here as users might be surprised to receive a Program_Error. Instead, a new aspect could be introduced. Lastly, around 20 years ago it was possible to apply the atomic aspect to all access-to-protected-subprogram types. I don't know if the old implementation did what I am describing here, but if it did, it's long gone from the compiler anyway.
