14967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//===- unittests/Lex/HeaderMapTest.cpp - HeaderMap tests ----------===//
24967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//
34967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//                     The LLVM Compiler Infrastructure
44967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//
54967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source
64967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// License. See LICENSE.TXT for details.
74967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//
84967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar//===--------------------------------------------------------------===//
94967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/Basic/CharInfo.h"
114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/Lex/HeaderMap.h"
124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "clang/Lex/HeaderMapTypes.h"
134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/ADT/SmallString.h"
144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "llvm/Support/SwapByteOrder.h"
154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include "gtest/gtest.h"
164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include <cassert>
174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#include <type_traits>
184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarusing namespace clang;
204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarusing namespace llvm;
214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarnamespace {
234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// Lay out a header file for testing.
254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainartemplate <unsigned NumBuckets, unsigned NumBytes> struct MapFile {
264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  HMapHeader Header;
274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  HMapBucket Buckets[NumBuckets];
284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned char Bytes[NumBytes];
294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void init() {
314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    memset(this, 0, sizeof(MapFile));
324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Header.Magic = HMAP_HeaderMagicNumber;
334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Header.Version = HMAP_HeaderVersion;
344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Header.NumBuckets = NumBuckets;
354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Header.StringsOffset = sizeof(Header) + sizeof(Buckets);
364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void swapBytes() {
394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    using llvm::sys::getSwappedBytes;
404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Header.Magic = getSwappedBytes(Header.Magic);
414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Header.Version = getSwappedBytes(Header.Version);
424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Header.NumBuckets = getSwappedBytes(Header.NumBuckets);
434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Header.StringsOffset = getSwappedBytes(Header.StringsOffset);
444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  std::unique_ptr<const MemoryBuffer> getBuffer() const {
474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return MemoryBuffer::getMemBuffer(
484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        StringRef(reinterpret_cast<const char *>(this), sizeof(MapFile)),
494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        "header",
504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        /* RequresNullTerminator */ false);
514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// The header map hash function.
554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstatic inline unsigned getHash(StringRef Str) {
564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned Result = 0;
574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (char C : Str)
584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Result += toLowercase(C) * 13;
594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return Result;
604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainartemplate <class FileTy> struct FileMaker {
634967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FileTy &File;
644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned SI = 1;
654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned BI = 0;
664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FileMaker(FileTy &File) : File(File) {}
674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  unsigned addString(StringRef S) {
694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(SI + S.size() + 1 <= sizeof(File.Bytes));
704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    std::copy(S.begin(), S.end(), File.Bytes + SI);
714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    auto OldSI = SI;
724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    SI += S.size() + 1;
734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return OldSI;
744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void addBucket(unsigned Hash, unsigned Key, unsigned Prefix, unsigned Suffix) {
764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    assert(!(File.Header.NumBuckets & (File.Header.NumBuckets - 1)));
774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    unsigned I = Hash & (File.Header.NumBuckets - 1);
784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    do {
794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (!File.Buckets[I].Key) {
804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        File.Buckets[I].Key = Key;
814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        File.Buckets[I].Prefix = Prefix;
824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        File.Buckets[I].Suffix = Suffix;
834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        ++File.Header.NumEntries;
844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        return;
854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++I;
874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      I &= File.Header.NumBuckets - 1;
884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    } while (I != (Hash & (File.Header.NumBuckets - 1)));
894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    llvm_unreachable("no empty buckets");
904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
934967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarTEST(HeaderMapTest, checkHeaderEmpty) {
944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsSwap;
954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(HeaderMapImpl::checkHeader(
964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      *MemoryBuffer::getMemBufferCopy("", "empty"), NeedsSwap));
974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(HeaderMapImpl::checkHeader(
984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      *MemoryBuffer::getMemBufferCopy("", "empty"), NeedsSwap));
994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
1004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1014967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarTEST(HeaderMapTest, checkHeaderMagic) {
1024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MapFile<1, 1> File;
1034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.init();
1044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.Header.Magic = 0;
1054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsSwap;
1064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
1074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
1084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1094967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarTEST(HeaderMapTest, checkHeaderReserved) {
1104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MapFile<1, 1> File;
1114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.init();
1124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.Header.Reserved = 1;
1134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsSwap;
1144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
1154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
1164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1174967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarTEST(HeaderMapTest, checkHeaderVersion) {
1184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MapFile<1, 1> File;
1194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.init();
1204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ++File.Header.Version;
1214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsSwap;
1224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
1234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
1244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1254967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarTEST(HeaderMapTest, checkHeaderValidButEmpty) {
1264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MapFile<1, 1> File;
1274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.init();
1284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsSwap;
1294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
1304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(NeedsSwap);
1314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.swapBytes();
1334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
1344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_TRUE(NeedsSwap);
1354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
1364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1374967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarTEST(HeaderMapTest, checkHeader3Buckets) {
1384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MapFile<3, 1> File;
1394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_EQ(3 * sizeof(HMapBucket), sizeof(File.Buckets));
1404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.init();
1424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsSwap;
1434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
1444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
1454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1464967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarTEST(HeaderMapTest, checkHeader0Buckets) {
1474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create with 1 bucket to avoid 0-sized arrays.
1484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MapFile<1, 1> File;
1494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.init();
1504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.Header.NumBuckets = 0;
1514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsSwap;
1524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
1534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
1544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1554967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarTEST(HeaderMapTest, checkHeaderNotEnoughBuckets) {
1564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  MapFile<1, 1> File;
1574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.init();
1584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.Header.NumBuckets = 8;
1594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsSwap;
1604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
1614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
1624967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1634967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarTEST(HeaderMapTest, lookupFilename) {
1644967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  typedef MapFile<2, 7> FileTy;
1654967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FileTy File;
1664967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.init();
1674967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1684967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FileMaker<FileTy> Maker(File);
1694967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto a = Maker.addString("a");
1704967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto b = Maker.addString("b");
1714967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto c = Maker.addString("c");
1724967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Maker.addBucket(getHash("a"), a, b, c);
1734967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsSwap;
1754967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
1764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(NeedsSwap);
1774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  HeaderMapImpl Map(File.getBuffer(), NeedsSwap);
1784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  SmallString<8> DestPath;
1804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_EQ("bc", Map.lookupFilename("a", DestPath));
1814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
1824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainartemplate <class FileTy, class PaddingTy> struct PaddedFile {
1844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FileTy File;
1854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  PaddingTy Padding;
1864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
1874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1884967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarTEST(HeaderMapTest, lookupFilenameTruncatedSuffix) {
1894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  typedef MapFile<2, 64 - sizeof(HMapHeader) - 2 * sizeof(HMapBucket)> FileTy;
1904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static_assert(std::is_standard_layout<FileTy>::value,
1914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                "Expected standard layout");
1924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static_assert(sizeof(FileTy) == 64, "check the math");
1934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  PaddedFile<FileTy, uint64_t> P;
1944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &File = P.File;
1954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &Padding = P.Padding;
1964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.init();
1974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FileMaker<FileTy> Maker(File);
1994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto a = Maker.addString("a");
2004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto b = Maker.addString("b");
2014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto c = Maker.addString("c");
2024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Maker.addBucket(getHash("a"), a, b, c);
2034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Add 'x' characters to cause an overflow into Padding.
2054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_EQ('c', File.Bytes[5]);
2064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (unsigned I = 6; I < sizeof(File.Bytes); ++I) {
2074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ASSERT_EQ(0, File.Bytes[I]);
2084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    File.Bytes[I] = 'x';
2094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Padding = 0xffffffff; // Padding won't stop it either.
2114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsSwap;
2134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
2144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(NeedsSwap);
2154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  HeaderMapImpl Map(File.getBuffer(), NeedsSwap);
2164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // The string for "c" runs to the end of File.  Check that the suffix
2184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // ("cxxxx...") is detected as truncated, and an empty string is returned.
2194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  SmallString<24> DestPath;
2204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_EQ("", Map.lookupFilename("a", DestPath));
2214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
2224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2234967a710c84587c654b56c828382219c3937dacbPirama Arumuga NainarTEST(HeaderMapTest, lookupFilenameTruncatedPrefix) {
2244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  typedef MapFile<2, 64 - sizeof(HMapHeader) - 2 * sizeof(HMapBucket)> FileTy;
2254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static_assert(std::is_standard_layout<FileTy>::value,
2264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                "Expected standard layout");
2274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  static_assert(sizeof(FileTy) == 64, "check the math");
2284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  PaddedFile<FileTy, uint64_t> P;
2294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &File = P.File;
2304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto &Padding = P.Padding;
2314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  File.init();
2324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  FileMaker<FileTy> Maker(File);
2344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto a = Maker.addString("a");
2354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto c = Maker.addString("c");
2364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  auto b = Maker.addString("b"); // Store the prefix last.
2374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Maker.addBucket(getHash("a"), a, b, c);
2384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Add 'x' characters to cause an overflow into Padding.
2404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_EQ('b', File.Bytes[5]);
2414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  for (unsigned I = 6; I < sizeof(File.Bytes); ++I) {
2424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    ASSERT_EQ(0, File.Bytes[I]);
2434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    File.Bytes[I] = 'x';
2444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
2454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  Padding = 0xffffffff; // Padding won't stop it either.
2464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool NeedsSwap;
2484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_TRUE(HeaderMapImpl::checkHeader(*File.getBuffer(), NeedsSwap));
2494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_FALSE(NeedsSwap);
2504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  HeaderMapImpl Map(File.getBuffer(), NeedsSwap);
2514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // The string for "b" runs to the end of File.  Check that the prefix
2534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // ("bxxxx...") is detected as truncated, and an empty string is returned.
2544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  SmallString<24> DestPath;
2554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ASSERT_EQ("", Map.lookupFilename("a", DestPath));
2564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
2574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // end namespace
259