Intrinsic subprograms in Pure packages were not marked as Pure, which was actually unintended. The spec of einfo was also not up-to-date, which is now fixed.
Tested on x86_64-pc-linux-gnu, committed on trunk 2014-02-04 Arnaud Charlet <char...@adacore.com> * g-souinf.ads: Subprograms in this unit are actually not pure. * freeze.adb (Freeze_Subprogram): Do not reset Is_Pure for Intrinsics. * einfo.ads (Is_Pure): Update doc to match implementation.
Index: g-souinf.ads =================================================================== --- g-souinf.ads (revision 207465) +++ g-souinf.ads (working copy) @@ -37,7 +37,14 @@ -- the name of the source file in which the exception is handled. package GNAT.Source_Info is - pragma Pure; + pragma Preelaborate; + -- Note that this unit is Preelaborate, but not Pure, that's because the + -- functions here such as Line are clearly not pure functions, and normally + -- we mark intrinsic functions in a Pure unit as Pure, even though they are + -- imported. + -- + -- Historical note: this used to be Pure, but that was when we marked all + -- intrinsics as not Pure, even in Pure units, so no problems arose. function File return String; -- Return the name of the current file, not including the path information. Index: einfo.ads =================================================================== --- einfo.ads (revision 207465) +++ einfo.ads (working copy) @@ -2775,13 +2775,13 @@ -- Is_Pure (Flag44) -- Defined in all entities. Set in all entities of a unit to which a --- pragma Pure is applied, and also set for the entity of the unit --- itself. In addition, this flag may be set for any other functions --- or procedures that are known to be side effect free, so in the case --- of subprograms, the Is_Pure flag may be used by the optimizer to --- imply that it can assume freedom from side effects (other than those --- resulting from assignment to out parameters, or to objects designated --- by access parameters). +-- pragma Pure is applied except for non intrinsic imported subprogram, +-- and also set for the entity of the unit itself. In addition, this +-- flag may be set for any other functions or procedures that are known +-- to be side effect free, so in the case of subprograms, the Is_Pure +-- flag may be used by the optimizer to imply that it can assume freedom +-- from side effects (other than those resulting from assignment to out +-- parameters, or to objects designated by access parameters). -- Is_Pure_Unit_Access_Type (Flag189) -- Defined in access type and subtype entities. Set if the type or Index: freeze.adb =================================================================== --- freeze.adb (revision 207466) +++ freeze.adb (working copy) @@ -6514,15 +6514,17 @@ end if; -- Reset the Pure indication on an imported subprogram unless an - -- explicit Pure_Function pragma was present. We do this because - -- otherwise it is an insidious error to call a non-pure function from - -- pure unit and have calls mysteriously optimized away. What happens - -- here is that the Import can bypass the normal check to ensure that - -- pure units call only pure subprograms. + -- explicit Pure_Function pragma was present or the subprogram is an + -- intrinsic. We do this because otherwise it is an insidious error + -- to call a non-pure function from pure unit and have calls + -- mysteriously optimized away. What happens here is that the Import + -- can bypass the normal check to ensure that pure units call only pure + -- subprograms. if Is_Imported (E) and then Is_Pure (E) and then not Has_Pragma_Pure_Function (E) + and then not Is_Intrinsic_Subprogram (E) then Set_Is_Pure (E, False); end if;