Skip to content

Commit fff15fd

Browse files
committed
Fix template specialization for optional type and add a test
1 parent e479863 commit fff15fd

File tree

4 files changed

+126
-6
lines changed

4 files changed

+126
-6
lines changed

compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ template <typename T> struct removeConst<const T> {
2222
using type = T;
2323
};
2424

25+
// This is only used for SFINAE when detecting if a type is defined.
26+
template <typename T> struct voidAdaptor {
27+
using type = void;
28+
};
29+
2530
} // namespace
2631

2732
namespace scudo {
@@ -38,12 +43,13 @@ namespace scudo {
3843
};
3944

4045
#define OPTIONAL_TYPE_TEMPLATE(NAME, DEFAULT, MEMBER) \
41-
template <typename Config, typename Void = Config> struct NAME##Type { \
46+
template <typename Config, typename Void = void> struct NAME##Type { \
4247
static constexpr bool enabled() { return false; } \
4348
using NAME = DEFAULT; \
4449
}; \
4550
template <typename Config> \
46-
struct NAME##Type<Config, typename Config::MEMBER> { \
51+
struct NAME##Type<Config, \
52+
typename voidAdaptor<typename Config::MEMBER>::type> { \
4753
static constexpr bool enabled() { return true; } \
4854
using NAME = typename Config::MEMBER; \
4955
};

compiler-rt/lib/scudo/standalone/primary64.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ template <typename Config> class SizeClassAllocator64 {
4949
public:
5050
typedef typename Config::CompactPtrT CompactPtrT;
5151
typedef typename Config::SizeClassMap SizeClassMap;
52-
#if 0
53-
typedef typename ConditionVariableState<
54-
typename Config::Primary>::ConditionVariableT ConditionVariableT;
55-
#endif
5652
typedef typename Config::ConditionVariableT ConditionVariableT;
5753
static const uptr CompactPtrScale = Config::getCompactPtrScale();
5854
static const uptr RegionSizeLog = Config::getRegionSizeLog();

compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ macro(add_scudo_unittest testname)
9090
endmacro()
9191

9292
set(SCUDO_UNIT_TEST_SOURCES
93+
allocator_config_test.cpp
9394
atomic_test.cpp
9495
bytemap_test.cpp
9596
checksum_test.cpp
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//===-- allocator_config_test.cpp -------------------------------*- C++ -*-===//
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 "tests/scudo_unit_test.h"
10+
11+
#include "allocator_config.h"
12+
#include "allocator_config_wrapper.h"
13+
#include "common.h"
14+
#include "secondary.h"
15+
16+
#include <type_traits>
17+
18+
struct TestBaseConfig {
19+
template <typename> using TSDRegistryT = void;
20+
template <typename> using PrimaryT = void;
21+
template <typename> using SecondaryT = void;
22+
};
23+
24+
struct TestBaseConfigEnableOptionalFlag : public TestBaseConfig {
25+
static const bool MaySupportMemoryTagging = true;
26+
// Use the getter to avoid the test to `use` the address of static const
27+
// variable (which requires additional explicit definition).
28+
static bool getMaySupportMemoryTagging() { return MaySupportMemoryTagging; }
29+
};
30+
31+
struct TestBasePrimaryConfig {
32+
using SizeClassMap = void;
33+
static const scudo::uptr RegionSizeLog = 18U;
34+
static const scudo::uptr GroupSizeLog = 18U;
35+
static const scudo::s32 MinReleaseToOsIntervalMs = INT32_MIN;
36+
static const scudo::s32 MaxReleaseToOsIntervalMs = INT32_MAX;
37+
typedef scudo::uptr CompactPtrT;
38+
static const scudo::uptr CompactPtrScale = 0;
39+
static const scudo::uptr MapSizeIncrement = 1UL << 18;
40+
};
41+
42+
struct TestPrimaryConfig : public TestBaseConfig {
43+
struct Primary : TestBasePrimaryConfig {};
44+
};
45+
46+
struct TestPrimaryConfigEnableOptionalFlag : public TestBaseConfig {
47+
struct Primary : TestBasePrimaryConfig {
48+
static const bool EnableRandomOffset = true;
49+
static bool getEnableRandomOffset() { return EnableRandomOffset; }
50+
};
51+
};
52+
53+
struct TestPrimaryConfigEnableOptionalType : public TestBaseConfig {
54+
struct DummyConditionVariable {};
55+
56+
struct Primary : TestBasePrimaryConfig {
57+
using ConditionVariableT = DummyConditionVariable;
58+
};
59+
};
60+
61+
struct TestSecondaryConfig : public TestPrimaryConfig {
62+
struct Secondary {
63+
template <typename Config>
64+
using CacheT = scudo::MapAllocatorNoCache<Config>;
65+
};
66+
};
67+
68+
struct TestSecondaryCacheConfigEnableOptionalFlag : public TestPrimaryConfig {
69+
struct Secondary {
70+
struct Cache {
71+
static const scudo::u32 EntriesArraySize = 256U;
72+
static scudo::u32 getEntriesArraySize() { return EntriesArraySize; }
73+
};
74+
template <typename T> using CacheT = scudo::MapAllocatorCache<T>;
75+
};
76+
};
77+
78+
TEST(ScudoAllocatorConfigTest, VerifyOptionalFlags) {
79+
// Test the top level allocator optional config.
80+
//
81+
// `MaySupportMemoryTagging` is default off.
82+
EXPECT_FALSE(scudo::BaseConfig<TestBaseConfig>::getMaySupportMemoryTagging());
83+
EXPECT_EQ(scudo::BaseConfig<
84+
TestBaseConfigEnableOptionalFlag>::getMaySupportMemoryTagging(),
85+
TestBaseConfigEnableOptionalFlag::getMaySupportMemoryTagging());
86+
87+
// Test primary optional config.
88+
//
89+
// `EnableRandomeOffset` is default off.
90+
EXPECT_FALSE(
91+
scudo::PrimaryConfig<TestPrimaryConfig>::getEnableRandomOffset());
92+
EXPECT_EQ(
93+
scudo::PrimaryConfig<
94+
TestPrimaryConfigEnableOptionalFlag>::getEnableRandomOffset(),
95+
TestPrimaryConfigEnableOptionalFlag::Primary::getEnableRandomOffset());
96+
97+
// `ConditionVariableT` is default off.
98+
EXPECT_FALSE(
99+
scudo::PrimaryConfig<TestPrimaryConfig>::hasConditionVariableT());
100+
EXPECT_TRUE((std::is_same_v<
101+
typename scudo::PrimaryConfig<
102+
TestPrimaryConfigEnableOptionalType>::ConditionVariableT,
103+
typename TestPrimaryConfigEnableOptionalType::Primary::
104+
ConditionVariableT>));
105+
106+
// Test secondary cache optional config.
107+
using NoCacheConfig =
108+
scudo::SecondaryConfig<TestSecondaryConfig>::CacheConfig;
109+
// `EntriesArraySize` is default 0.
110+
EXPECT_EQ(NoCacheConfig::getEntriesArraySize(), 0U);
111+
112+
using CacheConfig = scudo::SecondaryConfig<
113+
TestSecondaryCacheConfigEnableOptionalFlag>::CacheConfig;
114+
EXPECT_EQ(CacheConfig::getEntriesArraySize(),
115+
TestSecondaryCacheConfigEnableOptionalFlag::Secondary::Cache::
116+
getEntriesArraySize());
117+
}

0 commit comments

Comments
 (0)