xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_range.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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