diff --git a/compiler-rt/lib/scudo/standalone/secondary.h b/compiler-rt/lib/scudo/standalone/secondary.h --- a/compiler-rt/lib/scudo/standalone/secondary.h +++ b/compiler-rt/lib/scudo/standalone/secondary.h @@ -176,12 +176,12 @@ useMemoryTagging(Options)) { QuarantinePos = (QuarantinePos + 1) % Max(Config::SecondaryCacheQuarantineSize, 1u); - if (!Quarantine[QuarantinePos].CommitBase) { - Quarantine[QuarantinePos] = Entry; + if (!Quarantine.get(QuarantinePos)->CommitBase) { + *Quarantine.get(QuarantinePos) = Entry; return; } - CachedBlock PrevEntry = Quarantine[QuarantinePos]; - Quarantine[QuarantinePos] = Entry; + CachedBlock PrevEntry = *Quarantine.get(QuarantinePos); + *Quarantine.get(QuarantinePos) = Entry; if (OldestTime == 0) OldestTime = Entry.Time; Entry = PrevEntry; @@ -305,10 +305,10 @@ void disableMemoryTagging() { ScopedLock L(Mutex); for (u32 I = 0; I != Config::SecondaryCacheQuarantineSize; ++I) { - if (Quarantine[I].CommitBase) { - unmap(reinterpret_cast(Quarantine[I].MapBase), - Quarantine[I].MapSize, UNMAP_ALL, &Quarantine[I].Data); - Quarantine[I].CommitBase = 0; + if (Quarantine.get(I)->CommitBase) { + unmap(reinterpret_cast(Quarantine.get(I)->MapBase), + Quarantine.get(I)->MapSize, UNMAP_ALL, &Quarantine.get(I)->Data); + Quarantine.get(I)->CommitBase = 0; } } const u32 MaxCount = atomic_load_relaxed(&MaxEntriesCount); @@ -362,6 +362,18 @@ u64 Time; }; + // Template specialization to avoid producing zero-length array + template class QuarantineBlocks { + public: + CachedBlock *get(uptr Idx) { return &Blocks[Idx]; } + private: + CachedBlock Blocks[Size]; + }; + template <> class QuarantineBlocks<0> { + public: + CachedBlock *get(uptr UNUSED Idx) { return nullptr; } + }; + void releaseIfOlderThan(CachedBlock &Entry, u64 Time) { if (!Entry.CommitBase || !Entry.Time) return; @@ -380,7 +392,7 @@ return; OldestTime = 0; for (uptr I = 0; I < Config::SecondaryCacheQuarantineSize; I++) - releaseIfOlderThan(Quarantine[I], Time); + releaseIfOlderThan(*Quarantine.get(I), Time); for (uptr I = 0; I < Config::SecondaryCacheEntriesArraySize; I++) releaseIfOlderThan(Entries[I], Time); } @@ -395,7 +407,7 @@ atomic_s32 ReleaseToOsIntervalMs = {}; CachedBlock Entries[Config::SecondaryCacheEntriesArraySize] = {}; - CachedBlock Quarantine[Config::SecondaryCacheQuarantineSize] = {}; + QuarantineBlocks Quarantine = {}; }; template class MapAllocator {