Skip to content

Commit b15aa7f

Browse files
committed
[ORC] Add unit test for MemoryFlags APIs, don't dereference end() iterator.
In AllocGroupSmallMap::find(AllocGroup) we were calling lower_bound(...) and then unconditionally dereferencing the resulting iterator, however lower_bound(...) may return end() if the value being searched for is higher than any value present in the map. This patch adds a check for end() before the dereference to guard against dereference of end(). This commit also adds some basic unit tests for MemProt and AllocGroupSmallMap. rdar://129662981
1 parent 4c73b1a commit b15aa7f

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

llvm/include/llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ template <typename T> class AllocGroupSmallMap {
184184
iterator end() { return Elems.end(); }
185185
iterator find(AllocGroup G) {
186186
auto I = lower_bound(Elems, G, compareKey);
187-
return (I->first == G) ? I : end();
187+
return (I == end() || I->first == G) ? I : end();
188188
}
189189

190190
bool empty() const { return Elems.empty(); }

llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ add_llvm_unittest(OrcJITTests
2828
LookupAndRecordAddrsTest.cpp
2929
MachOPlatformTest.cpp
3030
MapperJITLinkMemoryManagerTest.cpp
31+
MemoryFlagsTest.cpp
3132
MemoryMapperTest.cpp
3233
ObjectFormatsTest.cpp
3334
ObjectLinkingLayerTest.cpp
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//===------- MemoryFlagsTest.cpp - Test MemoryFlags and related APIs ------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
10+
#include "gtest/gtest.h"
11+
12+
#include <future>
13+
14+
using namespace llvm;
15+
using namespace llvm::orc;
16+
17+
TEST(MemProtTest, Basics) {
18+
MemProt MPNone = MemProt::None;
19+
20+
EXPECT_EQ(MPNone & MemProt::Read, MemProt::None);
21+
EXPECT_EQ(MPNone & MemProt::Write, MemProt::None);
22+
EXPECT_EQ(MPNone & MemProt::Exec, MemProt::None);
23+
24+
EXPECT_EQ(MPNone | MemProt::Read, MemProt::Read);
25+
EXPECT_EQ(MPNone | MemProt::Write, MemProt::Write);
26+
EXPECT_EQ(MPNone | MemProt::Exec, MemProt::Exec);
27+
28+
MemProt MPAll = MemProt::Read | MemProt::Write | MemProt::Exec;
29+
EXPECT_EQ(MPAll & MemProt::Read, MemProt::Read);
30+
EXPECT_EQ(MPAll & MemProt::Write, MemProt::Write);
31+
EXPECT_EQ(MPAll & MemProt::Exec, MemProt::Exec);
32+
}
33+
34+
TEST(AllocGroupSmallMap, EmptyMap) {
35+
AllocGroupSmallMap<bool> EM;
36+
EXPECT_TRUE(EM.empty());
37+
EXPECT_EQ(EM.size(), 0u);
38+
}
39+
40+
TEST(AllocGroupSmallMap, NonEmptyMap) {
41+
AllocGroupSmallMap<unsigned> NEM;
42+
NEM[MemProt::Read] = 42;
43+
44+
EXPECT_FALSE(NEM.empty());
45+
EXPECT_EQ(NEM.size(), 1U);
46+
EXPECT_EQ(NEM[MemProt::Read], 42U);
47+
EXPECT_EQ(NEM.find(MemProt::Read), NEM.begin());
48+
EXPECT_EQ(NEM.find(MemProt::Read | MemProt::Write), NEM.end());
49+
50+
NEM[MemProt::Read | MemProt::Write] = 7;
51+
EXPECT_EQ(NEM.size(), 2U);
52+
EXPECT_EQ(NEM.begin()->second, 42U);
53+
EXPECT_EQ((NEM.begin() + 1)->second, 7U);
54+
}
55+

0 commit comments

Comments
 (0)