RM 11.4.2 stipulates that the optional string argument in an Assert pragma is evaluated only if the assertion fails and the string is incorporated into the raise statement. Previous to this patch the string expression was evaluated unconditionally, leading to unwanted side effects if its evaluation only made sense in case of failure of the assertion.
Executing: gnatmake -gnata -gnatws -q main main must yield: Assert succeeds raised SYSTEM.ASSERTIONS.ASSERT_FAILURE : P should be null, got A_STRING --- with Text_IO; use Text_IO; procedure Main is P : access String; X : Integer; function Zero return Integer is begin return 0; end; begin X := Zero; pragma Assert (P = null, "P should be null, got " & P.all); Put_Line ("Assert succeeds"); if X = 0 then P := new String'("A_STRING"); end if; pragma Assert (P = null, "P should be null, got " & P.all); end Main; Tested on x86_64-pc-linux-gnu, committed on trunk 2017-10-14 Ed Schonberg <schonb...@adacore.com> * sem_prag.adb (Analyze_Pragma, case Check): Defer evaluation of the optional string in an Assert pragma until the expansion of the pragma has rewritten it as a conditional statement, so that the string argument is only evaluaed if the assertion fails. This is mandated by RM 11.4.2.
Index: sem_prag.adb =================================================================== --- sem_prag.adb (revision 253754) +++ sem_prag.adb (working copy) @@ -13249,16 +13249,18 @@ -- If checks are not on we don't want any expansion (since -- such expansion would not get properly deleted) but -- we do want to analyze (to get proper references). - -- The Preanalyze_And_Resolve routine does just what we want + -- The Preanalyze_And_Resolve routine does just what we want. + -- Ditto if pragma is active, because it will be rewritten + -- as an if-statement whose analysis will complete analysis + -- and expansion of the string message. This makes a + -- difference in the unusual case where the expression for + -- the string may have a side effect, such as raising an + -- exception. This is mandated by RM 11.4.2, which specifies + -- that the string expression is only evaluated if the + -- check fails and Assertion_Error is to be raised. - if Is_Ignored (N) then - Preanalyze_And_Resolve (Str, Standard_String); + Preanalyze_And_Resolve (Str, Standard_String); - -- Otherwise we need a proper analysis and expansion - - else - Analyze_And_Resolve (Str, Standard_String); - end if; end if; -- Now you might think we could just do the same with the Boolean