The semantics of Merge changed slightly per AI05-0021. It was originally the case that if Target and Source denoted the same container object, then the GNAT implementation of Merge did nothing. However, it was argued that RM05 did not precisely specify the semantics for this corner case. The decision of the ARG was that if Target and Source denote the same non-empty container object, then Program_Error is raised.
The text of AI05-0021 can be found here: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai05s/ai05-0021-1.txt Tested on x86_64-pc-linux-gnu, committed on trunk 2011-11-04 Matthew Heaney <hea...@adacore.com> * a-convec.adb, a-coinve.adb, a-cobove.adb (Merge): Raise PE when Target and Source denote same non-empty object * a-cdlili.adb, a-cidlli.adb, a-cbdlli.adb (Merge): Ditto
Index: a-cdlili.adb =================================================================== --- a-cdlili.adb (revision 180934) +++ a-cdlili.adb (working copy) @@ -515,10 +515,24 @@ LI, RI : Cursor; begin - if Target'Address = Source'Address then + + -- The semantics of Merge changed slightly per AI05-0021. It was + -- originally the case that if Target and Source denoted the same + -- container object, then the GNAT implementation of Merge did + -- nothing. However, it was argued that RM05 did not precisely + -- specify the semantics for this corner case. The decision of the + -- ARG was that if Target and Source denote the same non-empty + -- container object, then Program_Error is raised. + + if Source.Is_Empty then return; end if; + if Target'Address = Source'Address then + raise Program_Error with + "Target and Source denote same non-empty container"; + end if; + if Target.Busy > 0 then raise Program_Error with "attempt to tamper with cursors of Target (list is busy)"; Index: a-coinve.adb =================================================================== --- a-coinve.adb (revision 180934) +++ a-coinve.adb (working copy) @@ -1268,16 +1268,26 @@ I, J : Index_Type'Base; begin - if Target.Last < Index_Type'First then - Move (Target => Target, Source => Source); + + -- The semantics of Merge changed slightly per AI05-0021. It was + -- originally the case that if Target and Source denoted the same + -- container object, then the GNAT implementation of Merge did + -- nothing. However, it was argued that RM05 did not precisely + -- specify the semantics for this corner case. The decision of the + -- ARG was that if Target and Source denote the same non-empty + -- container object, then Program_Error is raised. + + if Source.Last < Index_Type'First then -- Source is empty return; end if; if Target'Address = Source'Address then - return; + raise Program_Error with + "Target and Source denote same non-empty container"; end if; - if Source.Last < Index_Type'First then + if Target.Last < Index_Type'First then -- Target is empty + Move (Target => Target, Source => Source); return; end if; Index: a-cidlli.adb =================================================================== --- a-cidlli.adb (revision 180934) +++ a-cidlli.adb (working copy) @@ -563,10 +563,24 @@ LI, RI : Cursor; begin - if Target'Address = Source'Address then + + -- The semantics of Merge changed slightly per AI05-0021. It was + -- originally the case that if Target and Source denoted the same + -- container object, then the GNAT implementation of Merge did + -- nothing. However, it was argued that RM05 did not precisely + -- specify the semantics for this corner case. The decision of the + -- ARG was that if Target and Source denote the same non-empty + -- container object, then Program_Error is raised. + + if Source.Is_Empty then return; end if; + if Target'Address = Source'Address then + raise Program_Error with + "Target and Source denote same non-empty container"; + end if; + if Target.Busy > 0 then raise Program_Error with "attempt to tamper with cursors of Target (list is busy)"; Index: a-cobove.adb =================================================================== --- a-cobove.adb (revision 180934) +++ a-cobove.adb (working copy) @@ -788,16 +788,26 @@ I, J : Count_Type; begin - if Target.Is_Empty then - Move (Target => Target, Source => Source); + + -- The semantics of Merge changed slightly per AI05-0021. It was + -- originally the case that if Target and Source denoted the same + -- container object, then the GNAT implementation of Merge did + -- nothing. However, it was argued that RM05 did not precisely + -- specify the semantics for this corner case. The decision of the + -- ARG was that if Target and Source denote the same non-empty + -- container object, then Program_Error is raised. + + if Source.Is_Empty then return; end if; if Target'Address = Source'Address then - return; + raise Program_Error with + "Target and Source denote same non-empty container"; end if; - if Source.Is_Empty then + if Target.Is_Empty then + Move (Target => Target, Source => Source); return; end if; Index: a-convec.adb =================================================================== --- a-convec.adb (revision 180934) +++ a-convec.adb (working copy) @@ -909,16 +909,26 @@ J : Index_Type'Base; begin - if Target.Last < Index_Type'First then - Move (Target => Target, Source => Source); + + -- The semantics of Merge changed slightly per AI05-0021. It was + -- originally the case that if Target and Source denoted the same + -- container object, then the GNAT implementation of Merge did + -- nothing. However, it was argued that RM05 did not precisely + -- specify the semantics for this corner case. The decision of the + -- ARG was that if Target and Source denote the same non-empty + -- container object, then Program_Error is raised. + + if Source.Last < Index_Type'First then -- Source is empty return; end if; if Target'Address = Source'Address then - return; + raise Program_Error with + "Target and Source denote same non-empty container"; end if; - if Source.Last < Index_Type'First then + if Target.Last < Index_Type'First then -- Target is empty + Move (Target => Target, Source => Source); return; end if; Index: a-cbdlli.adb =================================================================== --- a-cbdlli.adb (revision 180934) +++ a-cbdlli.adb (working copy) @@ -713,10 +713,24 @@ LI, RI : Cursor; begin - if Target'Address = Source'Address then + + -- The semantics of Merge changed slightly per AI05-0021. It was + -- originally the case that if Target and Source denoted the same + -- container object, then the GNAT implementation of Merge did + -- nothing. However, it was argued that RM05 did not precisely + -- specify the semantics for this corner case. The decision of the + -- ARG was that if Target and Source denote the same non-empty + -- container object, then Program_Error is raised. + + if Source.Is_Empty then return; end if; + if Target'Address = Source'Address then + raise Program_Error with + "Target and Source denote same non-empty container"; + end if; + if Target.Busy > 0 then raise Program_Error with "attempt to tamper with cursors of Target (list is busy)";