| ------------------------------------------------------------------------------ |
| -- -- |
| -- GNAT COMPILER COMPONENTS -- |
| -- -- |
| -- S T R U B -- |
| -- -- |
| -- S p e c -- |
| -- -- |
| -- Copyright (C) 2021-2022, Free Software Foundation, Inc. -- |
| -- -- |
| -- GNAT is free software; you can redistribute it and/or modify it under -- |
| -- terms of the GNU General Public License as published by the Free Soft- -- |
| -- ware Foundation; either version 3, or (at your option) any later ver- -- |
| -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- |
| -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- |
| -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- |
| -- for more details. You should have received a copy of the GNU General -- |
| -- Public License distributed with GNAT; see file COPYING3. If not, go to -- |
| -- http://www.gnu.org/licenses for a complete copy of the license. -- |
| -- -- |
| -- GNAT was originally developed by the GNAT team at New York University. -- |
| -- Extensive contributions were provided by Ada Core Technologies Inc. -- |
| -- -- |
| ------------------------------------------------------------------------------ |
| |
| -- Package containing utility procedures related to Stack Scrubbing |
| |
| with Types; use Types; |
| |
| package Strub is |
| type Strub_Mode is |
| (Disabled, -- Subprogram cannot be called from strub contexts |
| At_Calls, -- Subprogram strubbed by caller |
| Internal, -- Subprogram strubbed by wrapper |
| Callable, -- Subprogram safe to call despite no strub |
| Unspecified, -- Subprogram or data without strub annotation |
| Enabled, -- Data (variable or constant) that enables strub |
| Not_Applicable); -- Entities that are not strub-capable |
| -- This is the type that expresses decoded strub annotations |
| |
| -- We compare strub modes in the following circumstances: |
| |
| -- * subprogram definition vs specification |
| -- * overriding vs overridden dispatch subprograms |
| -- * implementation vs interface dispatch subprogram |
| -- * renaming vs renamed subprogram |
| -- * type resolution |
| -- * explicit conversions |
| |
| -- Explicit conversions can convert between strub modes other than |
| -- at-calls (see Compatible_Strub_Modes), but for the other cases |
| -- above, we insist on identity of the strub modes (see |
| -- Check_Same_Strub_Mode). Anything else would be |
| -- troublesome. |
| |
| -- E.g., overriding a callable subprogram with a strub-disabled |
| -- implementation would enable a subprogram that's unsafe to call |
| -- in strub contexts to be called through a dispatching |
| -- interface. An explicitly strub-disabled subprogram shall not be |
| -- called from strub contexts, and a callable overriding |
| -- subprogram would still seem not-callable, so accepting |
| -- different modes would be surprising. |
| |
| -- We could relax the requirement for overriders from equality to |
| -- compatibility, with the understanding that the dispatching ABI |
| -- is what prevails. For renaming, however, if we don't require |
| -- equality, it would have to encompass an implicit conversion. |
| |
| procedure Check_Same_Strub_Mode |
| (Dest, Src : Entity_Id; |
| Report : Boolean := True); |
| -- Check whether Dest and Src are subprograms or subprogram types |
| -- annotated (or not) with the same strub mode. If Report is |
| -- requested, and the strub modes are not equivalent, an error |
| -- message is issued. Unspecified and Internal are considered |
| -- equivalent, because Internal is an internal implementation |
| -- detail. Unspecified decays to Disabled or Callable depending on |
| -- -fstrub=(strict|relaxed), but this procedure does not take this |
| -- decay into account, which avoids turning strub-equivalent |
| -- declarations into incompatible ones at command-line changes. |
| |
| function Compatible_Strub_Modes |
| (Dest, Src : Entity_Id) return Boolean; |
| -- Return True if Dest and Src are subprograms or subprogram types |
| -- annotated (or not) with ABI-compatible strub modes. At-calls is |
| -- incompatible to other strub modes, because the back end |
| -- internally modifies the signature of such subprograms, adding |
| -- hidden parameters. Calling a subprogram through an |
| -- access-to-subprogram object converted between strub-at-calls |
| -- and other strub modes should be deemed equivalent to |
| -- dereferencing an uninitialized access-to-data object, though |
| -- one-way conversions might seem to work in some circumstances. |
| -- |
| -- Unspecified, Disabled, Internal and Callable |
| -- (access-to-)subprograms, on the other hand, can be safely but |
| -- explicitly converted to each other, because these strub modes |
| -- do not require signature changes; so it is possible to alter |
| -- the caller-side stack scrubbing semantics of the call (e.g. to |
| -- call a subprogram that isn't strub-callable from within a strub |
| -- context, or to prevent it from being called through an access |
| -- object) without any incompatibilities. |
| |
| procedure Copy_Strub_Mode (Dest, Src : Entity_Id); |
| -- Copy the strub mode from Src to Dest, subprograms or subprogram |
| -- types. Dest is required to not have a strub mode already set. |
| |
| function Explicit_Strub_Mode (Id : Entity_Id) return Strub_Mode; |
| -- Return the strub mode associated with Id, that should refer to |
| -- a subprogram, a data object, or a type. |
| |
| function Strub_Pragma_P (Item : Node_Id) return Boolean; |
| -- Return True iff Item is a strub annotation, specifically, one |
| -- introduced by pragma Machine_Attribute (Entity, "strub"[, "mode"]). |
| |
| end Strub; |