1*06c3fb27SDimitry Andric //===-- sanitizer_range.cpp -----------------------------------------------===//
2*06c3fb27SDimitry Andric //
3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*06c3fb27SDimitry Andric //
7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
8*06c3fb27SDimitry Andric
9*06c3fb27SDimitry Andric #include "sanitizer_range.h"
10*06c3fb27SDimitry Andric
11*06c3fb27SDimitry Andric #include "sanitizer_common/sanitizer_array_ref.h"
12*06c3fb27SDimitry Andric
13*06c3fb27SDimitry Andric namespace __sanitizer {
14*06c3fb27SDimitry Andric
Intersect(ArrayRef<Range> a,ArrayRef<Range> b,InternalMmapVectorNoCtor<Range> & output)15*06c3fb27SDimitry Andric void Intersect(ArrayRef<Range> a, ArrayRef<Range> b,
16*06c3fb27SDimitry Andric InternalMmapVectorNoCtor<Range> &output) {
17*06c3fb27SDimitry Andric output.clear();
18*06c3fb27SDimitry Andric
19*06c3fb27SDimitry Andric struct Event {
20*06c3fb27SDimitry Andric uptr val;
21*06c3fb27SDimitry Andric s8 diff1;
22*06c3fb27SDimitry Andric s8 diff2;
23*06c3fb27SDimitry Andric };
24*06c3fb27SDimitry Andric
25*06c3fb27SDimitry Andric InternalMmapVector<Event> events;
26*06c3fb27SDimitry Andric for (const Range &r : a) {
27*06c3fb27SDimitry Andric CHECK_LE(r.begin, r.end);
28*06c3fb27SDimitry Andric events.push_back({r.begin, 1, 0});
29*06c3fb27SDimitry Andric events.push_back({r.end, -1, 0});
30*06c3fb27SDimitry Andric }
31*06c3fb27SDimitry Andric
32*06c3fb27SDimitry Andric for (const Range &r : b) {
33*06c3fb27SDimitry Andric CHECK_LE(r.begin, r.end);
34*06c3fb27SDimitry Andric events.push_back({r.begin, 0, 1});
35*06c3fb27SDimitry Andric events.push_back({r.end, 0, -1});
36*06c3fb27SDimitry Andric }
37*06c3fb27SDimitry Andric
38*06c3fb27SDimitry Andric Sort(events.data(), events.size(),
39*06c3fb27SDimitry Andric [](const Event &lh, const Event &rh) { return lh.val < rh.val; });
40*06c3fb27SDimitry Andric
41*06c3fb27SDimitry Andric uptr start = 0;
42*06c3fb27SDimitry Andric sptr state1 = 0;
43*06c3fb27SDimitry Andric sptr state2 = 0;
44*06c3fb27SDimitry Andric for (const auto &e : events) {
45*06c3fb27SDimitry Andric if (e.val != start) {
46*06c3fb27SDimitry Andric DCHECK_GE(state1, 0);
47*06c3fb27SDimitry Andric DCHECK_GE(state2, 0);
48*06c3fb27SDimitry Andric if (state1 && state2) {
49*06c3fb27SDimitry Andric if (!output.empty() && start == output.back().end)
50*06c3fb27SDimitry Andric output.back().end = e.val;
51*06c3fb27SDimitry Andric else
52*06c3fb27SDimitry Andric output.push_back({start, e.val});
53*06c3fb27SDimitry Andric }
54*06c3fb27SDimitry Andric start = e.val;
55*06c3fb27SDimitry Andric }
56*06c3fb27SDimitry Andric
57*06c3fb27SDimitry Andric state1 += e.diff1;
58*06c3fb27SDimitry Andric state2 += e.diff2;
59*06c3fb27SDimitry Andric }
60*06c3fb27SDimitry Andric }
61*06c3fb27SDimitry Andric
62*06c3fb27SDimitry Andric } // namespace __sanitizer
63