AI05-0022 requires that tampering checks be performed in order to detect manipulation of the container via generic actual subprograms. (In the case of the ordered maps, that would occur through generic operators "<" for Key_Type and "=" for Element_Type.)
However, for an empty container, no such check is strictly required, as we obtain the result without having to invoke any generic formal subprograms (because there are no elements). To ensure that there is no unnecessary manipulation of container state, we handle an empty container as a special case, and return a result immediately, without performing a tampering check. Tested on x86_64-pc-linux-gnu, committed on trunk 2013-04-25 Matthew Heaney <hea...@adacore.com> * a-rbtgbo.adb, a-crbtgo.adb (Generic_Equal): do not test for tampering when container empty. * a-crbtgk.adb (Ceiling, Find, Floor): ditto. (Generic_Conditional_Insert, Generic_Conditional_Insert_With_Hint): ditto.
Index: a-crbtgk.adb =================================================================== --- a-crbtgk.adb (revision 198221) +++ a-crbtgk.adb (working copy) @@ -45,6 +45,13 @@ X : Node_Access; begin + -- If the container is empty, return a result immediately, so that we do + -- not manipulate the tamper bits unnecessarily. + + if Tree.Root = null then + return null; + end if; + -- Per AI05-0022, the container implementation is required to detect -- element tampering by a generic actual subprogram. @@ -87,6 +94,13 @@ Result : Node_Access; begin + -- If the container is empty, return a result immediately, so that we do + -- not manipulate the tamper bits unnecessarily. + + if Tree.Root = null then + return null; + end if; + -- Per AI05-0022, the container implementation is required to detect -- element tampering by a generic actual subprogram. @@ -137,6 +151,13 @@ X : Node_Access; begin + -- If the container is empty, return a result immediately, so that we do + -- not manipulate the tamper bits unnecessarily. + + if Tree.Root = null then + return null; + end if; + -- Per AI05-0022, the container implementation is required to detect -- element tampering by a generic actual subprogram. @@ -198,6 +219,15 @@ -- its previous neighbor, in order for the conditional insertion to -- succeed. + -- Handle insertion into an empty container as a special case, so that + -- we do not manipulate the tamper bits unnecessarily. + + if Tree.Root = null then + Insert_Post (Tree, null, True, Node); + Inserted := True; + return; + end if; + -- We search the tree to find the nearest neighbor of Key, which is -- either the smallest node greater than Key (Inserted is True), or the -- largest node less or equivalent to Key (Inserted is False). @@ -227,9 +257,9 @@ if Inserted then - -- Either Tree is empty, or Key is less than Y. If Y is the first - -- node in the tree, then there are no other nodes that we need to - -- search for, and we insert a new node into the tree. + -- Key is less than Y. If Y is the first node in the tree, then there + -- are no other nodes that we need to search for, and we insert a new + -- node into the tree. if Y = Tree.First then Insert_Post (Tree, Y, True, Node); @@ -316,18 +346,26 @@ -- is not a search and the only comparisons that occur are with -- the hint and its neighbor. - -- If Position is null, this is interpreted to mean that Key is - -- large relative to the nodes in the tree. If the tree is empty, - -- or Key is greater than the last node in the tree, then we're - -- done; otherwise the hint was "wrong" and we must search. + -- Handle insertion into an empty container as a special case, so that + -- we do not manipulate the tamper bits unnecessarily. + if Tree.Root = null then + Insert_Post (Tree, null, True, Node); + Inserted := True; + return; + end if; + + -- If Position is null, this is interpreted to mean that Key is large + -- relative to the nodes in the tree. If Key is greater than the last + -- node in the tree, then we're done; otherwise the hint was "wrong" and + -- we must search. + if Position = null then -- largest begin B := B + 1; L := L + 1; - Compare := - Tree.Last = null or else Is_Greater_Key_Node (Key, Tree.Last); + Compare := Is_Greater_Key_Node (Key, Tree.Last); L := L - 1; B := B - 1; Index: a-crbtgo.adb =================================================================== --- a-crbtgo.adb (revision 198221) +++ a-crbtgo.adb (working copy) @@ -646,6 +646,13 @@ return False; end if; + -- If the containers are empty, return a result immediately, so as to + -- not manipulate the tamper bits unnecessarily. + + if Left.Length = 0 then + return True; + end if; + -- Per AI05-0022, the container implementation is required to detect -- element tampering by a generic actual subprogram. Index: a-rbtgbo.adb =================================================================== --- a-rbtgbo.adb (revision 198221) +++ a-rbtgbo.adb (working copy) @@ -626,6 +626,13 @@ return False; end if; + -- If the containers are empty, return a result immediately, so as to + -- not manipulate the tamper bits unnecessarily. + + if Left.Length = 0 then + return True; + end if; + -- Per AI05-0022, the container implementation is required to detect -- element tampering by a generic actual subprogram.