llvm-project
185 строк · 5.5 Кб
1//===- unittests/Lex/HeaderMapTest.cpp - HeaderMap tests ----------===//
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 "HeaderMapTestUtils.h"10#include "llvm/ADT/SmallString.h"11#include "gtest/gtest.h"12#include <type_traits>13
14using namespace clang;15using namespace llvm;16using namespace clang::test;17
18namespace {19
20TEST(HeaderMapTest, checkHeaderEmpty) {21bool NeedsSwap;22ASSERT_FALSE(HeaderMapImpl::checkHeader(23*MemoryBuffer::getMemBufferCopy("", "empty"), NeedsSwap));24ASSERT_FALSE(HeaderMapImpl::checkHeader(25*MemoryBuffer::getMemBufferCopy("", "empty"), NeedsSwap));26}
27
28TEST(HeaderMapTest, checkHeaderMagic) {29HMapFileMock<1, 1> File;30File.init();31File.Header.Magic = 0;32bool NeedsSwap;33ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));34}
35
36TEST(HeaderMapTest, checkHeaderReserved) {37HMapFileMock<1, 1> File;38File.init();39File.Header.Reserved = 1;40bool NeedsSwap;41ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));42}
43
44TEST(HeaderMapTest, checkHeaderVersion) {45HMapFileMock<1, 1> File;46File.init();47++File.Header.Version;48bool NeedsSwap;49ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));50}
51
52TEST(HeaderMapTest, checkHeaderValidButEmpty) {53HMapFileMock<1, 1> File;54File.init();55bool NeedsSwap;56ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));57ASSERT_FALSE(NeedsSwap);58
59File.swapBytes();60ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));61ASSERT_TRUE(NeedsSwap);62}
63
64TEST(HeaderMapTest, checkHeader3Buckets) {65HMapFileMock<3, 1> File;66ASSERT_EQ(3 * sizeof(HMapBucket), sizeof(File.Buckets));67
68File.init();69bool NeedsSwap;70ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));71}
72
73TEST(HeaderMapTest, checkHeader0Buckets) {74// Create with 1 bucket to avoid 0-sized arrays.75HMapFileMock<1, 1> File;76File.init();77File.Header.NumBuckets = 0;78bool NeedsSwap;79ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));80}
81
82TEST(HeaderMapTest, checkHeaderNotEnoughBuckets) {83HMapFileMock<1, 1> File;84File.init();85File.Header.NumBuckets = 8;86bool NeedsSwap;87ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));88}
89
90TEST(HeaderMapTest, lookupFilename) {91typedef HMapFileMock<2, 7> FileTy;92FileTy File;93File.init();94
95HMapFileMockMaker<FileTy> Maker(File);96auto a = Maker.addString("a");97auto b = Maker.addString("b");98auto c = Maker.addString("c");99Maker.addBucket("a", a, b, c);100
101bool NeedsSwap;102ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));103ASSERT_FALSE(NeedsSwap);104HeaderMapImpl Map(File.getBuffer(), NeedsSwap);105
106SmallString<8> DestPath;107ASSERT_EQ("bc", Map.lookupFilename("a", DestPath));108}
109
110template <class FileTy, class PaddingTy> struct PaddedFile {111FileTy File;112PaddingTy Padding;113};114
115TEST(HeaderMapTest, lookupFilenameTruncatedSuffix) {116typedef HMapFileMock<2, 64 - sizeof(HMapHeader) - 2 * sizeof(HMapBucket)>117FileTy;118static_assert(std::is_standard_layout_v<FileTy>, "Expected standard layout");119static_assert(sizeof(FileTy) == 64, "check the math");120PaddedFile<FileTy, uint64_t> P;121auto &File = P.File;122auto &Padding = P.Padding;123File.init();124
125HMapFileMockMaker<FileTy> Maker(File);126auto a = Maker.addString("a");127auto b = Maker.addString("b");128auto c = Maker.addString("c");129Maker.addBucket("a", a, b, c);130
131// Add 'x' characters to cause an overflow into Padding.132ASSERT_EQ('c', File.Bytes[5]);133for (unsigned I = 6; I < sizeof(File.Bytes); ++I) {134ASSERT_EQ(0, File.Bytes[I]);135File.Bytes[I] = 'x';136}137Padding = 0xffffffff; // Padding won't stop it either.138
139bool NeedsSwap;140ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));141ASSERT_FALSE(NeedsSwap);142HeaderMapImpl Map(File.getBuffer(), NeedsSwap);143
144// The string for "c" runs to the end of File. Check that the suffix145// ("cxxxx...") is detected as truncated, and an empty string is returned.146SmallString<24> DestPath;147ASSERT_EQ("", Map.lookupFilename("a", DestPath));148}
149
150TEST(HeaderMapTest, lookupFilenameTruncatedPrefix) {151typedef HMapFileMock<2, 64 - sizeof(HMapHeader) - 2 * sizeof(HMapBucket)>152FileTy;153static_assert(std::is_standard_layout_v<FileTy>, "Expected standard layout");154static_assert(sizeof(FileTy) == 64, "check the math");155PaddedFile<FileTy, uint64_t> P;156auto &File = P.File;157auto &Padding = P.Padding;158File.init();159
160HMapFileMockMaker<FileTy> Maker(File);161auto a = Maker.addString("a");162auto c = Maker.addString("c");163auto b = Maker.addString("b"); // Store the prefix last.164Maker.addBucket("a", a, b, c);165
166// Add 'x' characters to cause an overflow into Padding.167ASSERT_EQ('b', File.Bytes[5]);168for (unsigned I = 6; I < sizeof(File.Bytes); ++I) {169ASSERT_EQ(0, File.Bytes[I]);170File.Bytes[I] = 'x';171}172Padding = 0xffffffff; // Padding won't stop it either.173
174bool NeedsSwap;175ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));176ASSERT_FALSE(NeedsSwap);177HeaderMapImpl Map(File.getBuffer(), NeedsSwap);178
179// The string for "b" runs to the end of File. Check that the prefix180// ("bxxxx...") is detected as truncated, and an empty string is returned.181SmallString<24> DestPath;182ASSERT_EQ("", Map.lookupFilename("a", DestPath));183}
184
185} // end namespace186