https://gcc.gnu.org/g:623ce60ee6e06c76cb2abb376af21bf7fd51874c
commit r16-2011-g623ce60ee6e06c76cb2abb376af21bf7fd51874c Author: Bob Duff <d...@adacore.com> Date: Tue Jun 24 19:32:32 2025 -0400 ada: Pragma Short_Circuit_And_Or Improve documentation of pragma Short_Circuit_And_Or. Also disallow renamings, because the semantics as currently implemented is confusing. gcc/ada/ChangeLog: * doc/gnat_rm/implementation_defined_pragmas.rst (Short_Circuit_And_Or): Add more documentation. * sem_ch8.adb (Analyze_Subprogram_Renaming): Disallow renamings. * gnat_rm.texi: Regenerate. Diff: --- .../doc/gnat_rm/implementation_defined_pragmas.rst | 32 ++++++++++++++++---- gcc/ada/gnat_rm.texi | 34 +++++++++++++++++----- gcc/ada/sem_ch8.adb | 34 ++++++++++++++++++++++ 3 files changed, 87 insertions(+), 13 deletions(-) diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst index 02013f1d9b12..3986298d11e9 100644 --- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst +++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst @@ -5914,13 +5914,33 @@ Syntax: pragma Short_Circuit_And_Or; -This configuration pragma causes any occurrence of the AND operator applied to -operands of type Standard.Boolean to be short-circuited (i.e. the AND operator -is treated as if it were AND THEN). Or is similarly treated as OR ELSE. This -may be useful in the context of certification protocols requiring the use of -short-circuited logical operators. If this configuration pragma occurs locally -within the file being compiled, it applies only to the file being compiled. +This configuration pragma causes the predefined AND and OR operators of +type Standard.Boolean to have short-circuit semantics. That is, they +behave like AND THEN and OR ELSE; the right-hand side is not evaluated +if the left-hand side determines the result. This may be useful in the +context of certification protocols requiring the use of short-circuited +logical operators. + There is no requirement that all units in a partition use this option. +However, mixing of short-circuit and non-short-circuit semantics can be +confusing. Therefore, the recommended use is to put the pragma in a +configuration file that applies to the whole program. Alternatively, if +you have a legacy library that should not use this pragma, you can put +it in a separate library project that does not use the pragma. +In any case, fine-grained mixing of the different semantics is not +recommended. If pragma ``Short_Circuit_And_Or`` is specified, then it +is illegal to rename the predefined Boolean AND and OR, or to pass +them to generic formal functions; this corresponds to the fact that +AND THEN and OR ELSE cannot be renamed nor passed as generic formal +functions. + +Note that this pragma has no effect on other logical operators -- +predefined operators of modular types, array-of-boolean types and types +derived from Standard.Boolean, nor user-defined operators. + +See also the pragma ``Unevaluated_Use_Of_Old`` and the restriction +``No_Direct_Boolean_Operators``, which may be useful in conjunction +with ``Short_Circuit_And_Or``. Pragma Short_Descriptors ======================== diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 79fb225a555f..b0a14b034bc5 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -19,7 +19,7 @@ @copying @quotation -GNAT Reference Manual , Jun 27, 2025 +GNAT Reference Manual , Jul 03, 2025 AdaCore @@ -7548,13 +7548,33 @@ Syntax: pragma Short_Circuit_And_Or; @end example -This configuration pragma causes any occurrence of the AND operator applied to -operands of type Standard.Boolean to be short-circuited (i.e. the AND operator -is treated as if it were AND THEN). Or is similarly treated as OR ELSE. This -may be useful in the context of certification protocols requiring the use of -short-circuited logical operators. If this configuration pragma occurs locally -within the file being compiled, it applies only to the file being compiled. +This configuration pragma causes the predefined AND and OR operators of +type Standard.Boolean to have short-circuit semantics. That is, they +behave like AND THEN and OR ELSE; the right-hand side is not evaluated +if the left-hand side determines the result. This may be useful in the +context of certification protocols requiring the use of short-circuited +logical operators. + There is no requirement that all units in a partition use this option. +However, mixing of short-circuit and non-short-circuit semantics can be +confusing. Therefore, the recommended use is to put the pragma in a +configuration file that applies to the whole program. Alternatively, if +you have a legacy library that should not use this pragma, you can put +it in a separate library project that does not use the pragma. +In any case, fine-grained mixing of the different semantics is not +recommended. If pragma @code{Short_Circuit_And_Or} is specified, then it +is illegal to rename the predefined Boolean AND and OR, or to pass +them to generic formal functions; this corresponds to the fact that +AND THEN and OR ELSE cannot be renamed nor passed as generic formal +functions. + +Note that this pragma has no effect on other logical operators – +predefined operators of modular types, array-of-boolean types and types +derived from Standard.Boolean, nor user-defined operators. + +See also the pragma @code{Unevaluated_Use_Of_Old} and the restriction +@code{No_Direct_Boolean_Operators}, which may be useful in conjunction +with @code{Short_Circuit_And_Or}. @node Pragma Short_Descriptors,Pragma Side_Effects,Pragma Short_Circuit_And_Or,Implementation Defined Pragmas @anchor{gnat_rm/implementation_defined_pragmas pragma-short-descriptors}@anchor{ed} diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb index db892d0a5bef..54066b4f23ea 100644 --- a/gcc/ada/sem_ch8.adb +++ b/gcc/ada/sem_ch8.adb @@ -4270,6 +4270,40 @@ package body Sem_Ch8 is Local_Restrict.Check_Actual_Subprogram_For_Instance (Actual_Subp_Name => Nam, Formal_Subp => Formal_Spec); end if; + + -- If pragma Short_Circuit_And_Or is specified, then we give an error + -- for renaming an operator that is made short circuit. + -- For example, this is illegal: + -- + -- function My_And (X, Y: Boolean) return Boolean renames "and"; + -- + -- if "and" denotes the usual predefined Boolean operator. Otherwise, + -- the semantics are confusing (sometimes short circuit, and sometimes + -- not, for calls to My_And). If we ever relax this rule, we will need + -- to clean up that run-time semantics. + + if Short_Circuit_And_Or + and then Chars (Old_S) in Name_Op_And | Name_Op_Or + and then In_Extended_Main_Source_Unit (N) + and then Etype (Old_S) = Standard_Boolean + and then Is_Intrinsic_Subprogram (Old_S) + then + if Comes_From_Source (N) then + Error_Msg_N + ("pragma Short_Circuit_And_Or disallows renaming of " & + "operator", N); + + -- Same error in case of an instantiation with My_And => "and" + + elsif Present (Corresponding_Formal_Spec (N)) then + Error_Msg_N + ("pragma Short_Circuit_And_Or disallows passing of " & + "operator as a generic actual", N); + + else + raise Program_Error; + end if; + end if; end Analyze_Subprogram_Renaming; -------------------------