diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-28 15:59:58 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-28 15:59:58 +0000 |
commit | 4360561d0d96a781b639fb4e8abe121808056a25 (patch) | |
tree | 88ac1f51173fc7d412e45ff0f937fb8970af4a7f | |
parent | 06ca3e998d9a447d3cc588830d48af246b5b040e (diff) | |
parent | 8efb27c704e4d0a84430e2559c7845346a1511e2 (diff) | |
download | scudo-android13-frc-conscrypt-release.tar.gz |
Snap for 8512216 from 8efb27c704e4d0a84430e2559c7845346a1511e2 to tm-frc-conscrypt-releaset_frc_con_330443020android13-frc-conscrypt-release
Change-Id: I8800376e44c742e0ef8940a969cd1330e852239b
-rw-r--r-- | Android.bp | 8 | ||||
-rw-r--r-- | standalone/checksum.cpp | 1 | ||||
-rw-r--r-- | standalone/checksum.h | 8 | ||||
-rw-r--r-- | standalone/chunk.h | 4 | ||||
-rw-r--r-- | standalone/combined.h | 4 | ||||
-rw-r--r-- | standalone/crc32_hw.cpp | 4 | ||||
-rw-r--r-- | standalone/memtag.h | 29 | ||||
-rw-r--r-- | standalone/platform.h | 2 | ||||
-rw-r--r-- | standalone/primary64.h | 4 | ||||
-rw-r--r-- | standalone/secondary.h | 20 | ||||
-rw-r--r-- | standalone/size_class_map.h | 2 | ||||
-rw-r--r-- | standalone/tests/checksum_test.cpp | 10 | ||||
-rw-r--r-- | standalone/tests/combined_test.cpp | 4 | ||||
-rw-r--r-- | standalone/tests/map_test.cpp | 2 | ||||
-rw-r--r-- | standalone/tests/memtag_test.cpp | 2 | ||||
-rw-r--r-- | standalone/tests/primary_test.cpp | 4 | ||||
-rw-r--r-- | standalone/tests/secondary_test.cpp | 3 | ||||
-rw-r--r-- | standalone/tsd_exclusive.h | 4 | ||||
-rw-r--r-- | standalone/wrappers_c.cpp | 2 | ||||
-rw-r--r-- | standalone/wrappers_c.h | 5 | ||||
-rw-r--r-- | standalone/wrappers_c_checks.h | 7 | ||||
-rw-r--r-- | standalone/wrappers_cpp.cpp | 4 |
22 files changed, 78 insertions, 55 deletions
diff --git a/Android.bp b/Android.bp index 3eaeef56e98..ab3fb0d0a34 100644 --- a/Android.bp +++ b/Android.bp @@ -149,9 +149,6 @@ cc_defaults { "bionic_libc_platform_headers", ], }, - linux_glibc: { - enabled: true, - }, native_bridge: { cflags: ["-DSCUDO_DISABLE_TBI"], }, @@ -214,10 +211,7 @@ cc_test { "-fno-emulated-tls", ], target: { - android: { - header_libs: ["bionic_libc_platform_headers"], - }, - linux_bionic: { + bionic: { header_libs: ["bionic_libc_platform_headers"], }, }, diff --git a/standalone/checksum.cpp b/standalone/checksum.cpp index 05d4ba54bfc..2c277391a2e 100644 --- a/standalone/checksum.cpp +++ b/standalone/checksum.cpp @@ -8,6 +8,7 @@ #include "checksum.h" #include "atomic_helpers.h" +#include "chunk.h" #if defined(__x86_64__) || defined(__i386__) #include <cpuid.h> diff --git a/standalone/checksum.h b/standalone/checksum.h index a63b1b4f064..0f787ce2b5c 100644 --- a/standalone/checksum.h +++ b/standalone/checksum.h @@ -12,12 +12,16 @@ #include "internal_defs.h" // Hardware CRC32 is supported at compilation via the following: -// - for i386 & x86_64: -msse4.2 +// - for i386 & x86_64: -mcrc32 (earlier: -msse4.2) // - for ARM & AArch64: -march=armv8-a+crc or -mcrc // An additional check must be performed at runtime as well to make sure the // emitted instructions are valid on the target host. -#ifdef __SSE4_2__ +#if defined(__CRC32__) +// NB: clang has <crc32intrin.h> but GCC does not +#include <smmintrin.h> +#define CRC32_INTRINSIC FIRST_32_SECOND_64(__builtin_ia32_crc32si, __builtin_ia32_crc32di) +#elif defined(__SSE4_2__) #include <smmintrin.h> #define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64) #endif diff --git a/standalone/chunk.h b/standalone/chunk.h index 69b8e1b12a9..0581420dfc9 100644 --- a/standalone/chunk.h +++ b/standalone/chunk.h @@ -25,7 +25,7 @@ inline u16 computeChecksum(u32 Seed, uptr Value, uptr *Array, uptr ArraySize) { // as opposed to only for crc32_hw.cpp. This means that other hardware // specific instructions were likely emitted at other places, and as a result // there is no reason to not use it here. -#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32) +#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32) u32 Crc = static_cast<u32>(CRC32_INTRINSIC(Seed, Value)); for (uptr I = 0; I < ArraySize; I++) Crc = static_cast<u32>(CRC32_INTRINSIC(Crc, Array[I])); @@ -42,7 +42,7 @@ inline u16 computeChecksum(u32 Seed, uptr Value, uptr *Array, uptr ArraySize) { Checksum = computeBSDChecksum(Checksum, Array[I]); return Checksum; } -#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32) +#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32) } namespace Chunk { diff --git a/standalone/combined.h b/standalone/combined.h index 371fb783a06..365720d4a5f 100644 --- a/standalone/combined.h +++ b/standalone/combined.h @@ -1271,8 +1271,8 @@ private: } static const size_t NumErrorReports = - sizeof(((scudo_error_info *)0)->reports) / - sizeof(((scudo_error_info *)0)->reports[0]); + sizeof(((scudo_error_info *)nullptr)->reports) / + sizeof(((scudo_error_info *)nullptr)->reports[0]); static void getInlineErrorInfo(struct scudo_error_info *ErrorInfo, size_t &NextErrorReport, uintptr_t FaultAddr, diff --git a/standalone/crc32_hw.cpp b/standalone/crc32_hw.cpp index 62841ba5101..d13c615498f 100644 --- a/standalone/crc32_hw.cpp +++ b/standalone/crc32_hw.cpp @@ -10,10 +10,10 @@ namespace scudo { -#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32) +#if defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32) u32 computeHardwareCRC32(u32 Crc, uptr Data) { return static_cast<u32>(CRC32_INTRINSIC(Crc, Data)); } -#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32) +#endif // defined(__CRC32__) || defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32) } // namespace scudo diff --git a/standalone/memtag.h b/standalone/memtag.h index df346bce1bd..7578aff17be 100644 --- a/standalone/memtag.h +++ b/standalone/memtag.h @@ -41,16 +41,16 @@ inline uint8_t extractTag(uptr Ptr) { return (Ptr >> 56) & 0xf; } inline constexpr bool archSupportsMemoryTagging() { return false; } -inline uptr archMemoryTagGranuleSize() { +inline NORETURN uptr archMemoryTagGranuleSize() { UNREACHABLE("memory tagging not supported"); } -inline uptr untagPointer(uptr Ptr) { +inline NORETURN uptr untagPointer(uptr Ptr) { (void)Ptr; UNREACHABLE("memory tagging not supported"); } -inline uint8_t extractTag(uptr Ptr) { +inline NORETURN uint8_t extractTag(uptr Ptr) { (void)Ptr; UNREACHABLE("memory tagging not supported"); } @@ -109,11 +109,11 @@ inline void enableSystemMemoryTaggingTestOnly() { inline bool systemSupportsMemoryTagging() { return false; } -inline bool systemDetectsMemoryTagFaultsTestOnly() { +inline NORETURN bool systemDetectsMemoryTagFaultsTestOnly() { UNREACHABLE("memory tagging not supported"); } -inline void enableSystemMemoryTaggingTestOnly() { +inline NORETURN void enableSystemMemoryTaggingTestOnly() { UNREACHABLE("memory tagging not supported"); } @@ -255,15 +255,15 @@ inline uptr loadTag(uptr Ptr) { #else -inline bool systemSupportsMemoryTagging() { +inline NORETURN bool systemSupportsMemoryTagging() { UNREACHABLE("memory tagging not supported"); } -inline bool systemDetectsMemoryTagFaultsTestOnly() { +inline NORETURN bool systemDetectsMemoryTagFaultsTestOnly() { UNREACHABLE("memory tagging not supported"); } -inline void enableSystemMemoryTaggingTestOnly() { +inline NORETURN void enableSystemMemoryTaggingTestOnly() { UNREACHABLE("memory tagging not supported"); } @@ -271,41 +271,44 @@ struct ScopedDisableMemoryTagChecks { ScopedDisableMemoryTagChecks() {} }; -inline uptr selectRandomTag(uptr Ptr, uptr ExcludeMask) { +inline NORETURN uptr selectRandomTag(uptr Ptr, uptr ExcludeMask) { (void)Ptr; (void)ExcludeMask; UNREACHABLE("memory tagging not supported"); } -inline uptr addFixedTag(uptr Ptr, uptr Tag) { +inline NORETURN uptr addFixedTag(uptr Ptr, uptr Tag) { (void)Ptr; (void)Tag; UNREACHABLE("memory tagging not supported"); } -inline uptr storeTags(uptr Begin, uptr End) { +inline NORETURN uptr storeTags(uptr Begin, uptr End) { (void)Begin; (void)End; UNREACHABLE("memory tagging not supported"); } -inline void storeTag(uptr Ptr) { +inline NORETURN void storeTag(uptr Ptr) { (void)Ptr; UNREACHABLE("memory tagging not supported"); } -inline uptr loadTag(uptr Ptr) { +inline NORETURN uptr loadTag(uptr Ptr) { (void)Ptr; UNREACHABLE("memory tagging not supported"); } #endif +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-noreturn" inline void setRandomTag(void *Ptr, uptr Size, uptr ExcludeMask, uptr *TaggedBegin, uptr *TaggedEnd) { *TaggedBegin = selectRandomTag(reinterpret_cast<uptr>(Ptr), ExcludeMask); *TaggedEnd = storeTags(*TaggedBegin, *TaggedBegin + Size); } +#pragma GCC diagnostic pop inline void *untagPointer(void *Ptr) { return reinterpret_cast<void *>(untagPointer(reinterpret_cast<uptr>(Ptr))); diff --git a/standalone/platform.h b/standalone/platform.h index 36378d14d84..db4217ddab9 100644 --- a/standalone/platform.h +++ b/standalone/platform.h @@ -37,7 +37,7 @@ #define SCUDO_TRUSTY 0 #endif -#if __LP64__ +#if defined(__LP64__) #define SCUDO_WORDSIZE 64U #else #define SCUDO_WORDSIZE 32U diff --git a/standalone/primary64.h b/standalone/primary64.h index 6c1785512c6..14784ee8f37 100644 --- a/standalone/primary64.h +++ b/standalone/primary64.h @@ -89,7 +89,9 @@ public: RegionInfo *Region = getRegionInfo(I); *Region = {}; } - unmap(reinterpret_cast<void *>(PrimaryBase), PrimarySize, UNMAP_ALL, &Data); + if (PrimaryBase) + unmap(reinterpret_cast<void *>(PrimaryBase), PrimarySize, UNMAP_ALL, + &Data); PrimaryBase = 0U; } diff --git a/standalone/secondary.h b/standalone/secondary.h index abb58a2882a..2d177576258 100644 --- a/standalone/secondary.h +++ b/standalone/secondary.h @@ -113,6 +113,19 @@ void mapSecondary(Options Options, uptr CommitBase, uptr CommitSize, } } +// Template specialization to avoid producing zero-length array +template <typename T, size_t Size> class NonZeroLengthArray { +public: + T &operator[](uptr Idx) { return values[Idx]; } + +private: + T values[Size]; +}; +template <typename T> class NonZeroLengthArray<T, 0> { +public: + T &operator[](uptr UNUSED Idx) { UNREACHABLE("Unsupported!"); } +}; + template <typename Config> class MapAllocatorCache { public: // Ensure the default maximum specified fits the array. @@ -219,7 +232,7 @@ public: const u32 MaxCount = atomic_load_relaxed(&MaxEntriesCount); bool Found = false; CachedBlock Entry; - uptr HeaderPos; + uptr HeaderPos = 0; { ScopedLock L(Mutex); if (EntriesCount == 0) @@ -395,7 +408,8 @@ private: atomic_s32 ReleaseToOsIntervalMs = {}; CachedBlock Entries[Config::SecondaryCacheEntriesArraySize] = {}; - CachedBlock Quarantine[Config::SecondaryCacheQuarantineSize] = {}; + NonZeroLengthArray<CachedBlock, Config::SecondaryCacheQuarantineSize> + Quarantine = {}; }; template <typename Config> class MapAllocator { @@ -445,7 +459,7 @@ public: } } - uptr canCache(uptr Size) { return Cache.canCache(Size); } + bool canCache(uptr Size) { return Cache.canCache(Size); } bool setOption(Option O, sptr Value) { return Cache.setOption(O, Value); } diff --git a/standalone/size_class_map.h b/standalone/size_class_map.h index 28b16d976e5..6b060950abe 100644 --- a/standalone/size_class_map.h +++ b/standalone/size_class_map.h @@ -345,7 +345,7 @@ template <typename SCMap> inline void printMap() { Buffer.output(); } -template <typename SCMap> static void validateMap() { +template <typename SCMap> static UNUSED void validateMap() { for (uptr C = 0; C < SCMap::NumClasses; C++) { if (C == SCMap::BatchClassId) continue; diff --git a/standalone/tests/checksum_test.cpp b/standalone/tests/checksum_test.cpp index 781f990ecb7..c5d5b737963 100644 --- a/standalone/tests/checksum_test.cpp +++ b/standalone/tests/checksum_test.cpp @@ -12,16 +12,16 @@ #include <string.h> -scudo::u16 computeSoftwareChecksum(scudo::u32 Seed, scudo::uptr *Array, - scudo::uptr ArraySize) { +static scudo::u16 computeSoftwareChecksum(scudo::u32 Seed, scudo::uptr *Array, + scudo::uptr ArraySize) { scudo::u16 Checksum = static_cast<scudo::u16>(Seed & 0xffff); for (scudo::uptr I = 0; I < ArraySize; I++) Checksum = scudo::computeBSDChecksum(Checksum, Array[I]); return Checksum; } -scudo::u16 computeHardwareChecksum(scudo::u32 Seed, scudo::uptr *Array, - scudo::uptr ArraySize) { +static scudo::u16 computeHardwareChecksum(scudo::u32 Seed, scudo::uptr *Array, + scudo::uptr ArraySize) { scudo::u32 Crc = Seed; for (scudo::uptr I = 0; I < ArraySize; I++) Crc = scudo::computeHardwareCRC32(Crc, Array[I]); @@ -32,7 +32,7 @@ typedef scudo::u16 (*ComputeChecksum)(scudo::u32, scudo::uptr *, scudo::uptr); // This verifies that flipping bits in the data being checksummed produces a // different checksum. We do not use random data to avoid flakyness. -template <ComputeChecksum F> void verifyChecksumFunctionBitFlip() { +template <ComputeChecksum F> static void verifyChecksumFunctionBitFlip() { scudo::uptr Array[sizeof(scudo::u64) / sizeof(scudo::uptr)]; const scudo::uptr ArraySize = ARRAY_SIZE(Array); memset(Array, 0xaa, sizeof(Array)); diff --git a/standalone/tests/combined_test.cpp b/standalone/tests/combined_test.cpp index deccccf4f1f..94d97df8167 100644 --- a/standalone/tests/combined_test.cpp +++ b/standalone/tests/combined_test.cpp @@ -118,7 +118,7 @@ template <typename T> using ScudoCombinedDeathTest = ScudoCombinedTest<T>; #define SCUDO_TYPED_TEST_TYPE(FIXTURE, NAME, TYPE) \ using FIXTURE##NAME##_##TYPE = FIXTURE##NAME<scudo::TYPE>; \ - TEST_F(FIXTURE##NAME##_##TYPE, NAME) { Run(); } + TEST_F(FIXTURE##NAME##_##TYPE, NAME) { FIXTURE##NAME<scudo::TYPE>::Run(); } #define SCUDO_TYPED_TEST(FIXTURE, NAME) \ template <class TypeParam> \ @@ -643,7 +643,7 @@ SCUDO_TYPED_TEST(ScudoCombinedTest, OddEven) { SCUDO_TYPED_TEST(ScudoCombinedTest, DisableMemInit) { auto *Allocator = this->Allocator.get(); - std::vector<void *> Ptrs(65536, nullptr); + std::vector<void *> Ptrs(65536); Allocator->setOption(scudo::Option::ThreadDisableMemInit, 1); diff --git a/standalone/tests/map_test.cpp b/standalone/tests/map_test.cpp index 095e1b6a5d2..ff05258db58 100644 --- a/standalone/tests/map_test.cpp +++ b/standalone/tests/map_test.cpp @@ -17,7 +17,7 @@ static const char *MappingName = "scudo:test"; TEST(ScudoMapTest, PageSize) { EXPECT_EQ(scudo::getPageSizeCached(), - static_cast<scudo::uptr>(getpagesize())); + static_cast<scudo::uptr>(sysconf(_SC_PAGESIZE))); } TEST(ScudoMapDeathTest, MapNoAccessUnmap) { diff --git a/standalone/tests/memtag_test.cpp b/standalone/tests/memtag_test.cpp index 72c9de36b8b..283edaa2a2c 100644 --- a/standalone/tests/memtag_test.cpp +++ b/standalone/tests/memtag_test.cpp @@ -38,7 +38,7 @@ TEST(MemtagBasicDeathTest, Unsupported) { EXPECT_DEATH(addFixedTag(nullptr, 0), "not supported"); } -class MemtagTest : public ::testing::Test { +class MemtagTest : public Test { protected: void SetUp() override { if (!archSupportsMemoryTagging() || !systemDetectsMemoryTagFaultsTestOnly()) diff --git a/standalone/tests/primary_test.cpp b/standalone/tests/primary_test.cpp index 5ec43619a2a..283e2973c1e 100644 --- a/standalone/tests/primary_test.cpp +++ b/standalone/tests/primary_test.cpp @@ -105,7 +105,7 @@ template <class BaseConfig> struct ScudoPrimaryTest : public Test {}; #define SCUDO_TYPED_TEST_TYPE(FIXTURE, NAME, TYPE) \ using FIXTURE##NAME##_##TYPE = FIXTURE##NAME<TYPE>; \ - TEST_F(FIXTURE##NAME##_##TYPE, NAME) { Run(); } + TEST_F(FIXTURE##NAME##_##TYPE, NAME) { FIXTURE##NAME<TYPE>::Run(); } #define SCUDO_TYPED_TEST(FIXTURE, NAME) \ template <class TypeParam> \ @@ -207,7 +207,7 @@ SCUDO_TYPED_TEST(ScudoPrimaryTest, PrimaryIterate) { V.push_back(std::make_pair(ClassId, P)); } scudo::uptr Found = 0; - auto Lambda = [V, &Found](scudo::uptr Block) { + auto Lambda = [&V, &Found](scudo::uptr Block) { for (const auto &Pair : V) { if (Pair.second == reinterpret_cast<void *>(Block)) Found++; diff --git a/standalone/tests/secondary_test.cpp b/standalone/tests/secondary_test.cpp index 723679228cb..e656466d68f 100644 --- a/standalone/tests/secondary_test.cpp +++ b/standalone/tests/secondary_test.cpp @@ -12,6 +12,7 @@ #include "allocator_config.h" #include "secondary.h" +#include <algorithm> #include <condition_variable> #include <memory> #include <mutex> @@ -152,7 +153,7 @@ TEST_F(MapAllocatorTest, SecondaryIterate) { const scudo::uptr PageSize = scudo::getPageSizeCached(); for (scudo::uptr I = 0; I < 32U; I++) V.push_back(Allocator->allocate(Options, (std::rand() % 16) * PageSize)); - auto Lambda = [V](scudo::uptr Block) { + auto Lambda = [&V](scudo::uptr Block) { EXPECT_NE(std::find(V.begin(), V.end(), reinterpret_cast<void *>(Block)), V.end()); }; diff --git a/standalone/tsd_exclusive.h b/standalone/tsd_exclusive.h index bba0c277c6a..d49427b2005 100644 --- a/standalone/tsd_exclusive.h +++ b/standalone/tsd_exclusive.h @@ -15,7 +15,7 @@ namespace scudo { struct ThreadState { bool DisableMemInit : 1; - enum { + enum : unsigned { NotInitialized = 0, Initialized, TornDown, @@ -87,7 +87,7 @@ template <class Allocator> struct TSDRegistryExT { Mutex.unlock(); } - bool setOption(Option O, UNUSED sptr Value) { + bool setOption(Option O, sptr Value) { if (O == Option::ThreadDisableMemInit) State.DisableMemInit = Value; if (O == Option::MaxTSDsCount) diff --git a/standalone/wrappers_c.cpp b/standalone/wrappers_c.cpp index 81c7dd60ee3..b4d51be716c 100644 --- a/standalone/wrappers_c.cpp +++ b/standalone/wrappers_c.cpp @@ -21,8 +21,6 @@ #define SCUDO_PREFIX(name) name #define SCUDO_ALLOCATOR Allocator -extern "C" void SCUDO_PREFIX(malloc_postinit)(); - // Export the static allocator so that the C++ wrappers can access it. // Technically we could have a completely separated heap for C & C++ but in // reality the amount of cross pollination between the two is staggering. diff --git a/standalone/wrappers_c.h b/standalone/wrappers_c.h index 5f7f51f3ced..08dc679b34c 100644 --- a/standalone/wrappers_c.h +++ b/standalone/wrappers_c.h @@ -54,4 +54,9 @@ struct __scudo_mallinfo2 { #define SCUDO_MALLINFO __scudo_mallinfo #endif +#if !SCUDO_ANDROID || !_BIONIC +extern "C" void malloc_postinit(); +extern HIDDEN scudo::Allocator<scudo::Config, malloc_postinit> Allocator; +#endif + #endif // SCUDO_WRAPPERS_C_H_ diff --git a/standalone/wrappers_c_checks.h b/standalone/wrappers_c_checks.h index ec9c1a104e8..815d40023b6 100644 --- a/standalone/wrappers_c_checks.h +++ b/standalone/wrappers_c_checks.h @@ -47,9 +47,12 @@ inline bool checkPosixMemalignAlignment(uptr Alignment) { // costly division. inline bool checkForCallocOverflow(uptr Size, uptr N, uptr *Product) { #if __has_builtin(__builtin_umull_overflow) && (SCUDO_WORDSIZE == 64U) - return __builtin_umull_overflow(Size, N, Product); + return __builtin_umull_overflow(Size, N, + reinterpret_cast<unsigned long *>(Product)); #elif __has_builtin(__builtin_umul_overflow) && (SCUDO_WORDSIZE == 32U) - return __builtin_umul_overflow(Size, N, Product); + // On, e.g. armv7, uptr/uintptr_t may be defined as unsigned long + return __builtin_umul_overflow(Size, N, + reinterpret_cast<unsigned int *>(Product)); #else *Product = Size * N; if (!Size) diff --git a/standalone/wrappers_cpp.cpp b/standalone/wrappers_cpp.cpp index adb10411812..16f495b6a35 100644 --- a/standalone/wrappers_cpp.cpp +++ b/standalone/wrappers_cpp.cpp @@ -12,12 +12,10 @@ #if !SCUDO_ANDROID || !_BIONIC #include "allocator_config.h" +#include "wrappers_c.h" #include <stdint.h> -extern "C" void malloc_postinit(); -extern HIDDEN scudo::Allocator<scudo::Config, malloc_postinit> Allocator; - namespace std { struct nothrow_t {}; enum class align_val_t : size_t {}; |