Imported Upstream version 5.18.0.205

Former-commit-id: 7f59f7e792705db773f1caecdaa823092f4e2927
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-11-16 08:20:38 +00:00
parent 5cd5df71cc
commit 8e12397d70
28486 changed files with 3867013 additions and 66 deletions

View File

@ -0,0 +1,384 @@
#include "llvm/Support/ARMAttributeParser.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include "gtest/gtest.h"
#include <string>
using namespace llvm;
struct AttributeSection {
unsigned Tag;
unsigned Value;
AttributeSection(unsigned tag, unsigned value) : Tag(tag), Value(value) { }
void write(raw_ostream &OS) {
OS.flush();
// length = length + "aeabi\0" + TagFile + ByteSize + Tag + Value;
// length = 17 bytes
OS << 'A' << (uint8_t)17 << (uint8_t)0 << (uint8_t)0 << (uint8_t)0;
OS << "aeabi" << '\0';
OS << (uint8_t)1 << (uint8_t)7 << (uint8_t)0 << (uint8_t)0 << (uint8_t)0;
OS << (uint8_t)Tag << (uint8_t)Value;
}
};
bool testBuildAttr(unsigned Tag, unsigned Value,
unsigned ExpectedTag, unsigned ExpectedValue) {
std::string buffer;
raw_string_ostream OS(buffer);
AttributeSection Section(Tag, Value);
Section.write(OS);
ArrayRef<uint8_t> Bytes(
reinterpret_cast<const uint8_t*>(OS.str().c_str()), OS.str().size());
ARMAttributeParser Parser;
Parser.Parse(Bytes, true);
return (Parser.hasAttribute(ExpectedTag) &&
Parser.getAttributeValue(ExpectedTag) == ExpectedValue);
}
bool testTagString(unsigned Tag, const char *name) {
return ARMBuildAttrs::AttrTypeAsString(Tag).str() == name;
}
TEST(CPUArchBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(6, "Tag_CPU_arch"));
EXPECT_TRUE(testBuildAttr(6, 0, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::Pre_v4));
EXPECT_TRUE(testBuildAttr(6, 1, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v4));
EXPECT_TRUE(testBuildAttr(6, 2, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v4T));
EXPECT_TRUE(testBuildAttr(6, 3, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v5T));
EXPECT_TRUE(testBuildAttr(6, 4, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v5TE));
EXPECT_TRUE(testBuildAttr(6, 5, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v5TEJ));
EXPECT_TRUE(testBuildAttr(6, 6, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v6));
EXPECT_TRUE(testBuildAttr(6, 7, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v6KZ));
EXPECT_TRUE(testBuildAttr(6, 8, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v6T2));
EXPECT_TRUE(testBuildAttr(6, 9, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v6K));
EXPECT_TRUE(testBuildAttr(6, 10, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v7));
EXPECT_TRUE(testBuildAttr(6, 11, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v6_M));
EXPECT_TRUE(testBuildAttr(6, 12, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v6S_M));
EXPECT_TRUE(testBuildAttr(6, 13, ARMBuildAttrs::CPU_arch,
ARMBuildAttrs::v7E_M));
}
TEST(CPUArchProfileBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(7, "Tag_CPU_arch_profile"));
EXPECT_TRUE(testBuildAttr(7, 'A', ARMBuildAttrs::CPU_arch_profile,
ARMBuildAttrs::ApplicationProfile));
EXPECT_TRUE(testBuildAttr(7, 'R', ARMBuildAttrs::CPU_arch_profile,
ARMBuildAttrs::RealTimeProfile));
EXPECT_TRUE(testBuildAttr(7, 'M', ARMBuildAttrs::CPU_arch_profile,
ARMBuildAttrs::MicroControllerProfile));
EXPECT_TRUE(testBuildAttr(7, 'S', ARMBuildAttrs::CPU_arch_profile,
ARMBuildAttrs::SystemProfile));
}
TEST(ARMISABuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(8, "Tag_ARM_ISA_use"));
EXPECT_TRUE(testBuildAttr(8, 0, ARMBuildAttrs::ARM_ISA_use,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(8, 1, ARMBuildAttrs::ARM_ISA_use,
ARMBuildAttrs::Allowed));
}
TEST(ThumbISABuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(9, "Tag_THUMB_ISA_use"));
EXPECT_TRUE(testBuildAttr(9, 0, ARMBuildAttrs::THUMB_ISA_use,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(9, 1, ARMBuildAttrs::THUMB_ISA_use,
ARMBuildAttrs::Allowed));
}
TEST(FPArchBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(10, "Tag_FP_arch"));
EXPECT_TRUE(testBuildAttr(10, 0, ARMBuildAttrs::FP_arch,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(10, 1, ARMBuildAttrs::FP_arch,
ARMBuildAttrs::Allowed));
EXPECT_TRUE(testBuildAttr(10, 2, ARMBuildAttrs::FP_arch,
ARMBuildAttrs::AllowFPv2));
EXPECT_TRUE(testBuildAttr(10, 3, ARMBuildAttrs::FP_arch,
ARMBuildAttrs::AllowFPv3A));
EXPECT_TRUE(testBuildAttr(10, 4, ARMBuildAttrs::FP_arch,
ARMBuildAttrs::AllowFPv3B));
EXPECT_TRUE(testBuildAttr(10, 5, ARMBuildAttrs::FP_arch,
ARMBuildAttrs::AllowFPv4A));
EXPECT_TRUE(testBuildAttr(10, 6, ARMBuildAttrs::FP_arch,
ARMBuildAttrs::AllowFPv4B));
EXPECT_TRUE(testBuildAttr(10, 7, ARMBuildAttrs::FP_arch,
ARMBuildAttrs::AllowFPARMv8A));
EXPECT_TRUE(testBuildAttr(10, 8, ARMBuildAttrs::FP_arch,
ARMBuildAttrs::AllowFPARMv8B));
}
TEST(WMMXBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(11, "Tag_WMMX_arch"));
EXPECT_TRUE(testBuildAttr(11, 0, ARMBuildAttrs::WMMX_arch,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(11, 1, ARMBuildAttrs::WMMX_arch,
ARMBuildAttrs::AllowWMMXv1));
EXPECT_TRUE(testBuildAttr(11, 2, ARMBuildAttrs::WMMX_arch,
ARMBuildAttrs::AllowWMMXv2));
}
TEST(SIMDBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(12, "Tag_Advanced_SIMD_arch"));
EXPECT_TRUE(testBuildAttr(12, 0, ARMBuildAttrs::Advanced_SIMD_arch,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(12, 1, ARMBuildAttrs::Advanced_SIMD_arch,
ARMBuildAttrs::AllowNeon));
EXPECT_TRUE(testBuildAttr(12, 2, ARMBuildAttrs::Advanced_SIMD_arch,
ARMBuildAttrs::AllowNeon2));
EXPECT_TRUE(testBuildAttr(12, 3, ARMBuildAttrs::Advanced_SIMD_arch,
ARMBuildAttrs::AllowNeonARMv8));
EXPECT_TRUE(testBuildAttr(12, 4, ARMBuildAttrs::Advanced_SIMD_arch,
ARMBuildAttrs::AllowNeonARMv8_1a));
}
TEST(FPHPBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(36, "Tag_FP_HP_extension"));
EXPECT_TRUE(testBuildAttr(36, 0, ARMBuildAttrs::FP_HP_extension,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(36, 1, ARMBuildAttrs::FP_HP_extension,
ARMBuildAttrs::AllowHPFP));
}
TEST(CPUAlignBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(34, "Tag_CPU_unaligned_access"));
EXPECT_TRUE(testBuildAttr(34, 0, ARMBuildAttrs::CPU_unaligned_access,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(34, 1, ARMBuildAttrs::CPU_unaligned_access,
ARMBuildAttrs::Allowed));
}
TEST(T2EEBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(66, "Tag_T2EE_use"));
EXPECT_TRUE(testBuildAttr(66, 0, ARMBuildAttrs::T2EE_use,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(66, 1, ARMBuildAttrs::T2EE_use,
ARMBuildAttrs::Allowed));
}
TEST(VirtualizationBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(68, "Tag_Virtualization_use"));
EXPECT_TRUE(testBuildAttr(68, 0, ARMBuildAttrs::Virtualization_use,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(68, 1, ARMBuildAttrs::Virtualization_use,
ARMBuildAttrs::AllowTZ));
EXPECT_TRUE(testBuildAttr(68, 2, ARMBuildAttrs::Virtualization_use,
ARMBuildAttrs::AllowVirtualization));
EXPECT_TRUE(testBuildAttr(68, 3, ARMBuildAttrs::Virtualization_use,
ARMBuildAttrs::AllowTZVirtualization));
}
TEST(MPBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(42, "Tag_MPextension_use"));
EXPECT_TRUE(testBuildAttr(42, 0, ARMBuildAttrs::MPextension_use,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(42, 1, ARMBuildAttrs::MPextension_use,
ARMBuildAttrs::AllowMP));
}
TEST(DivBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(44, "Tag_DIV_use"));
EXPECT_TRUE(testBuildAttr(44, 0, ARMBuildAttrs::DIV_use,
ARMBuildAttrs::AllowDIVIfExists));
EXPECT_TRUE(testBuildAttr(44, 1, ARMBuildAttrs::DIV_use,
ARMBuildAttrs::DisallowDIV));
EXPECT_TRUE(testBuildAttr(44, 2, ARMBuildAttrs::DIV_use,
ARMBuildAttrs::AllowDIVExt));
}
TEST(PCS_ConfigBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(13, "Tag_PCS_config"));
EXPECT_TRUE(testBuildAttr(13, 0, ARMBuildAttrs::PCS_config, 0));
EXPECT_TRUE(testBuildAttr(13, 1, ARMBuildAttrs::PCS_config, 1));
EXPECT_TRUE(testBuildAttr(13, 2, ARMBuildAttrs::PCS_config, 2));
EXPECT_TRUE(testBuildAttr(13, 3, ARMBuildAttrs::PCS_config, 3));
EXPECT_TRUE(testBuildAttr(13, 4, ARMBuildAttrs::PCS_config, 4));
EXPECT_TRUE(testBuildAttr(13, 5, ARMBuildAttrs::PCS_config, 5));
EXPECT_TRUE(testBuildAttr(13, 6, ARMBuildAttrs::PCS_config, 6));
EXPECT_TRUE(testBuildAttr(13, 7, ARMBuildAttrs::PCS_config, 7));
}
TEST(PCS_R9BuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(14, "Tag_ABI_PCS_R9_use"));
EXPECT_TRUE(testBuildAttr(14, 0, ARMBuildAttrs::ABI_PCS_R9_use,
ARMBuildAttrs::R9IsGPR));
EXPECT_TRUE(testBuildAttr(14, 1, ARMBuildAttrs::ABI_PCS_R9_use,
ARMBuildAttrs::R9IsSB));
EXPECT_TRUE(testBuildAttr(14, 2, ARMBuildAttrs::ABI_PCS_R9_use,
ARMBuildAttrs::R9IsTLSPointer));
EXPECT_TRUE(testBuildAttr(14, 3, ARMBuildAttrs::ABI_PCS_R9_use,
ARMBuildAttrs::R9Reserved));
}
TEST(PCS_RWBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(15, "Tag_ABI_PCS_RW_data"));
EXPECT_TRUE(testBuildAttr(15, 0, ARMBuildAttrs::ABI_PCS_RW_data,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(15, 1, ARMBuildAttrs::ABI_PCS_RW_data,
ARMBuildAttrs::AddressRWPCRel));
EXPECT_TRUE(testBuildAttr(15, 2, ARMBuildAttrs::ABI_PCS_RW_data,
ARMBuildAttrs::AddressRWSBRel));
EXPECT_TRUE(testBuildAttr(15, 3, ARMBuildAttrs::ABI_PCS_RW_data,
ARMBuildAttrs::AddressRWNone));
}
TEST(PCS_ROBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(16, "Tag_ABI_PCS_RO_data"));
EXPECT_TRUE(testBuildAttr(16, 0, ARMBuildAttrs::ABI_PCS_RO_data,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(16, 1, ARMBuildAttrs::ABI_PCS_RO_data,
ARMBuildAttrs::AddressROPCRel));
EXPECT_TRUE(testBuildAttr(16, 2, ARMBuildAttrs::ABI_PCS_RO_data,
ARMBuildAttrs::AddressRONone));
}
TEST(PCS_GOTBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(17, "Tag_ABI_PCS_GOT_use"));
EXPECT_TRUE(testBuildAttr(17, 0, ARMBuildAttrs::ABI_PCS_GOT_use,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(17, 1, ARMBuildAttrs::ABI_PCS_GOT_use,
ARMBuildAttrs::AddressDirect));
EXPECT_TRUE(testBuildAttr(17, 2, ARMBuildAttrs::ABI_PCS_GOT_use,
ARMBuildAttrs::AddressGOT));
}
TEST(PCS_WCharBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(18, "Tag_ABI_PCS_wchar_t"));
EXPECT_TRUE(testBuildAttr(18, 0, ARMBuildAttrs::ABI_PCS_wchar_t,
ARMBuildAttrs::WCharProhibited));
EXPECT_TRUE(testBuildAttr(18, 2, ARMBuildAttrs::ABI_PCS_wchar_t,
ARMBuildAttrs::WCharWidth2Bytes));
EXPECT_TRUE(testBuildAttr(18, 4, ARMBuildAttrs::ABI_PCS_wchar_t,
ARMBuildAttrs::WCharWidth4Bytes));
}
TEST(EnumSizeBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(26, "Tag_ABI_enum_size"));
EXPECT_TRUE(testBuildAttr(26, 0, ARMBuildAttrs::ABI_enum_size,
ARMBuildAttrs::EnumProhibited));
EXPECT_TRUE(testBuildAttr(26, 1, ARMBuildAttrs::ABI_enum_size,
ARMBuildAttrs::EnumSmallest));
EXPECT_TRUE(testBuildAttr(26, 2, ARMBuildAttrs::ABI_enum_size,
ARMBuildAttrs::Enum32Bit));
EXPECT_TRUE(testBuildAttr(26, 3, ARMBuildAttrs::ABI_enum_size,
ARMBuildAttrs::Enum32BitABI));
}
TEST(AlignNeededBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(24, "Tag_ABI_align_needed"));
EXPECT_TRUE(testBuildAttr(24, 0, ARMBuildAttrs::ABI_align_needed,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(24, 1, ARMBuildAttrs::ABI_align_needed,
ARMBuildAttrs::Align8Byte));
EXPECT_TRUE(testBuildAttr(24, 2, ARMBuildAttrs::ABI_align_needed,
ARMBuildAttrs::Align4Byte));
EXPECT_TRUE(testBuildAttr(24, 3, ARMBuildAttrs::ABI_align_needed,
ARMBuildAttrs::AlignReserved));
}
TEST(AlignPreservedBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(25, "Tag_ABI_align_preserved"));
EXPECT_TRUE(testBuildAttr(25, 0, ARMBuildAttrs::ABI_align_preserved,
ARMBuildAttrs::AlignNotPreserved));
EXPECT_TRUE(testBuildAttr(25, 1, ARMBuildAttrs::ABI_align_preserved,
ARMBuildAttrs::AlignPreserve8Byte));
EXPECT_TRUE(testBuildAttr(25, 2, ARMBuildAttrs::ABI_align_preserved,
ARMBuildAttrs::AlignPreserveAll));
EXPECT_TRUE(testBuildAttr(25, 3, ARMBuildAttrs::ABI_align_preserved,
ARMBuildAttrs::AlignReserved));
}
TEST(FPRoundingBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(19, "Tag_ABI_FP_rounding"));
EXPECT_TRUE(testBuildAttr(19, 0, ARMBuildAttrs::ABI_FP_rounding, 0));
EXPECT_TRUE(testBuildAttr(19, 1, ARMBuildAttrs::ABI_FP_rounding, 1));
}
TEST(FPDenormalBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(20, "Tag_ABI_FP_denormal"));
EXPECT_TRUE(testBuildAttr(20, 0, ARMBuildAttrs::ABI_FP_denormal,
ARMBuildAttrs::PositiveZero));
EXPECT_TRUE(testBuildAttr(20, 1, ARMBuildAttrs::ABI_FP_denormal,
ARMBuildAttrs::IEEEDenormals));
EXPECT_TRUE(testBuildAttr(20, 2, ARMBuildAttrs::ABI_FP_denormal,
ARMBuildAttrs::PreserveFPSign));
}
TEST(FPExceptionsBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(21, "Tag_ABI_FP_exceptions"));
EXPECT_TRUE(testBuildAttr(21, 0, ARMBuildAttrs::ABI_FP_exceptions, 0));
EXPECT_TRUE(testBuildAttr(21, 1, ARMBuildAttrs::ABI_FP_exceptions, 1));
}
TEST(FPUserExceptionsBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(22, "Tag_ABI_FP_user_exceptions"));
EXPECT_TRUE(testBuildAttr(22, 0, ARMBuildAttrs::ABI_FP_user_exceptions, 0));
EXPECT_TRUE(testBuildAttr(22, 1, ARMBuildAttrs::ABI_FP_user_exceptions, 1));
}
TEST(FPNumberModelBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(23, "Tag_ABI_FP_number_model"));
EXPECT_TRUE(testBuildAttr(23, 0, ARMBuildAttrs::ABI_FP_number_model,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(23, 1, ARMBuildAttrs::ABI_FP_number_model,
ARMBuildAttrs::AllowIEEENormal));
EXPECT_TRUE(testBuildAttr(23, 2, ARMBuildAttrs::ABI_FP_number_model,
ARMBuildAttrs::AllowRTABI));
EXPECT_TRUE(testBuildAttr(23, 3, ARMBuildAttrs::ABI_FP_number_model,
ARMBuildAttrs::AllowIEEE754));
}
TEST(FP16BuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(38, "Tag_ABI_FP_16bit_format"));
EXPECT_TRUE(testBuildAttr(38, 0, ARMBuildAttrs::ABI_FP_16bit_format,
ARMBuildAttrs::Not_Allowed));
EXPECT_TRUE(testBuildAttr(38, 1, ARMBuildAttrs::ABI_FP_16bit_format,
ARMBuildAttrs::FP16FormatIEEE));
EXPECT_TRUE(testBuildAttr(38, 2, ARMBuildAttrs::ABI_FP_16bit_format,
ARMBuildAttrs::FP16VFP3));
}
TEST(HardFPBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(27, "Tag_ABI_HardFP_use"));
EXPECT_TRUE(testBuildAttr(27, 0, ARMBuildAttrs::ABI_HardFP_use,
ARMBuildAttrs::HardFPImplied));
EXPECT_TRUE(testBuildAttr(27, 1, ARMBuildAttrs::ABI_HardFP_use,
ARMBuildAttrs::HardFPSinglePrecision));
EXPECT_TRUE(testBuildAttr(27, 2, ARMBuildAttrs::ABI_HardFP_use, 2));
}
TEST(VFPArgsBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(28, "Tag_ABI_VFP_args"));
EXPECT_TRUE(testBuildAttr(28, 0, ARMBuildAttrs::ABI_VFP_args,
ARMBuildAttrs::BaseAAPCS));
EXPECT_TRUE(testBuildAttr(28, 1, ARMBuildAttrs::ABI_VFP_args,
ARMBuildAttrs::HardFPAAPCS));
EXPECT_TRUE(testBuildAttr(28, 2, ARMBuildAttrs::ABI_VFP_args, 2));
EXPECT_TRUE(testBuildAttr(28, 3, ARMBuildAttrs::ABI_VFP_args, 3));
}
TEST(WMMXArgsBuildAttr, testBuildAttr) {
EXPECT_TRUE(testTagString(29, "Tag_ABI_WMMX_args"));
EXPECT_TRUE(testBuildAttr(29, 0, ARMBuildAttrs::ABI_WMMX_args, 0));
EXPECT_TRUE(testBuildAttr(29, 1, ARMBuildAttrs::ABI_WMMX_args, 1));
EXPECT_TRUE(testBuildAttr(29, 2, ARMBuildAttrs::ABI_WMMX_args, 2));
}

View File

@ -0,0 +1,249 @@
//=== - llvm/unittest/Support/AlignOfTest.cpp - Alignment utility tests ---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifdef _MSC_VER
// Disable warnings about alignment-based structure padding.
// This must be above the includes to suppress warnings in included templates.
#pragma warning(disable:4324)
#endif
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace {
// Disable warnings about questionable type definitions.
// We're testing that even questionable types work with the alignment utilities.
#ifdef _MSC_VER
#pragma warning(disable:4584)
#endif
// Suppress direct base '{anonymous}::S1' inaccessible in '{anonymous}::D9'
// due to ambiguity warning.
#ifdef __clang__
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Winaccessible-base"
#elif ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
// Pragma based warning suppression was introduced in GGC 4.2. Additionally
// this warning is "enabled by default". The warning still appears if -Wall is
// suppressed. Apparently GCC suppresses it when -w is specifed, which is odd.
#pragma GCC diagnostic warning "-w"
#endif
// Define some fixed alignment types to use in these tests.
struct LLVM_ALIGNAS(1) A1 {};
struct LLVM_ALIGNAS(2) A2 {};
struct LLVM_ALIGNAS(4) A4 {};
struct LLVM_ALIGNAS(8) A8 {};
struct S1 {};
struct S2 { char a; };
struct S3 { int x; };
struct S4 { double y; };
struct S5 { A1 a1; A2 a2; A4 a4; A8 a8; };
struct S6 { double f(); };
struct D1 : S1 {};
struct D2 : S6 { float g(); };
struct D3 : S2 {};
struct D4 : S2 { int x; };
struct D5 : S3 { char c; };
struct D6 : S2, S3 {};
struct D7 : S1, S3 {};
struct D8 : S1, D4, D5 { double x[2]; };
struct D9 : S1, D1 { S1 s1; };
struct V1 { virtual ~V1(); };
struct V2 { int x; virtual ~V2(); };
struct V3 : V1 {
~V3() override;
};
struct V4 : virtual V2 { int y;
~V4() override;
};
struct V5 : V4, V3 { double z;
~V5() override;
};
struct V6 : S1 { virtual ~V6(); };
struct V7 : virtual V2, virtual V6 {
~V7() override;
};
struct V8 : V5, virtual V6, V7 { double zz;
~V8() override;
};
double S6::f() { return 0.0; }
float D2::g() { return 0.0f; }
V1::~V1() {}
V2::~V2() {}
V3::~V3() {}
V4::~V4() {}
V5::~V5() {}
V6::~V6() {}
V7::~V7() {}
V8::~V8() {}
template <typename M> struct T { M m; };
TEST(AlignOfTest, BasicAlignedArray) {
EXPECT_LE(1u, alignof(AlignedCharArrayUnion<A1>));
EXPECT_LE(2u, alignof(AlignedCharArrayUnion<A2>));
EXPECT_LE(4u, alignof(AlignedCharArrayUnion<A4>));
EXPECT_LE(8u, alignof(AlignedCharArrayUnion<A8>));
EXPECT_LE(1u, sizeof(AlignedCharArrayUnion<A1>));
EXPECT_LE(2u, sizeof(AlignedCharArrayUnion<A2>));
EXPECT_LE(4u, sizeof(AlignedCharArrayUnion<A4>));
EXPECT_LE(8u, sizeof(AlignedCharArrayUnion<A8>));
EXPECT_EQ(1u, (alignof(AlignedCharArrayUnion<A1>)));
EXPECT_EQ(2u, (alignof(AlignedCharArrayUnion<A1, A2>)));
EXPECT_EQ(4u, (alignof(AlignedCharArrayUnion<A1, A2, A4>)));
EXPECT_EQ(8u, (alignof(AlignedCharArrayUnion<A1, A2, A4, A8>)));
EXPECT_EQ(1u, sizeof(AlignedCharArrayUnion<A1>));
EXPECT_EQ(2u, sizeof(AlignedCharArrayUnion<A1, A2>));
EXPECT_EQ(4u, sizeof(AlignedCharArrayUnion<A1, A2, A4>));
EXPECT_EQ(8u, sizeof(AlignedCharArrayUnion<A1, A2, A4, A8>));
EXPECT_EQ(1u, (alignof(AlignedCharArrayUnion<A1[1]>)));
EXPECT_EQ(2u, (alignof(AlignedCharArrayUnion<A1[2], A2[1]>)));
EXPECT_EQ(4u, (alignof(AlignedCharArrayUnion<A1[42], A2[55], A4[13]>)));
EXPECT_EQ(8u, (alignof(AlignedCharArrayUnion<A1[2], A2[1], A4, A8>)));
EXPECT_EQ(1u, sizeof(AlignedCharArrayUnion<A1[1]>));
EXPECT_EQ(2u, sizeof(AlignedCharArrayUnion<A1[2], A2[1]>));
EXPECT_EQ(4u, sizeof(AlignedCharArrayUnion<A1[3], A2[2], A4>));
EXPECT_EQ(16u, sizeof(AlignedCharArrayUnion<A1, A2[3],
A4[3], A8>));
// For other tests we simply assert that the alignment of the union mathes
// that of the fundamental type and hope that we have any weird type
// productions that would trigger bugs.
EXPECT_EQ(alignof(T<char>), alignof(AlignedCharArrayUnion<char>));
EXPECT_EQ(alignof(T<short>), alignof(AlignedCharArrayUnion<short>));
EXPECT_EQ(alignof(T<int>), alignof(AlignedCharArrayUnion<int>));
EXPECT_EQ(alignof(T<long>), alignof(AlignedCharArrayUnion<long>));
EXPECT_EQ(alignof(T<long long>), alignof(AlignedCharArrayUnion<long long>));
EXPECT_EQ(alignof(T<float>), alignof(AlignedCharArrayUnion<float>));
EXPECT_EQ(alignof(T<double>), alignof(AlignedCharArrayUnion<double>));
EXPECT_EQ(alignof(T<long double>),
alignof(AlignedCharArrayUnion<long double>));
EXPECT_EQ(alignof(T<void *>), alignof(AlignedCharArrayUnion<void *>));
EXPECT_EQ(alignof(T<int *>), alignof(AlignedCharArrayUnion<int *>));
EXPECT_EQ(alignof(T<double (*)(double)>),
alignof(AlignedCharArrayUnion<double (*)(double)>));
EXPECT_EQ(alignof(T<double (S6::*)()>),
alignof(AlignedCharArrayUnion<double (S6::*)()>));
EXPECT_EQ(alignof(S1), alignof(AlignedCharArrayUnion<S1>));
EXPECT_EQ(alignof(S2), alignof(AlignedCharArrayUnion<S2>));
EXPECT_EQ(alignof(S3), alignof(AlignedCharArrayUnion<S3>));
EXPECT_EQ(alignof(S4), alignof(AlignedCharArrayUnion<S4>));
EXPECT_EQ(alignof(S5), alignof(AlignedCharArrayUnion<S5>));
EXPECT_EQ(alignof(S6), alignof(AlignedCharArrayUnion<S6>));
EXPECT_EQ(alignof(D1), alignof(AlignedCharArrayUnion<D1>));
EXPECT_EQ(alignof(D2), alignof(AlignedCharArrayUnion<D2>));
EXPECT_EQ(alignof(D3), alignof(AlignedCharArrayUnion<D3>));
EXPECT_EQ(alignof(D4), alignof(AlignedCharArrayUnion<D4>));
EXPECT_EQ(alignof(D5), alignof(AlignedCharArrayUnion<D5>));
EXPECT_EQ(alignof(D6), alignof(AlignedCharArrayUnion<D6>));
EXPECT_EQ(alignof(D7), alignof(AlignedCharArrayUnion<D7>));
EXPECT_EQ(alignof(D8), alignof(AlignedCharArrayUnion<D8>));
EXPECT_EQ(alignof(D9), alignof(AlignedCharArrayUnion<D9>));
EXPECT_EQ(alignof(V1), alignof(AlignedCharArrayUnion<V1>));
EXPECT_EQ(alignof(V2), alignof(AlignedCharArrayUnion<V2>));
EXPECT_EQ(alignof(V3), alignof(AlignedCharArrayUnion<V3>));
EXPECT_EQ(alignof(V4), alignof(AlignedCharArrayUnion<V4>));
EXPECT_EQ(alignof(V5), alignof(AlignedCharArrayUnion<V5>));
EXPECT_EQ(alignof(V6), alignof(AlignedCharArrayUnion<V6>));
EXPECT_EQ(alignof(V7), alignof(AlignedCharArrayUnion<V7>));
// Some versions of MSVC get this wrong somewhat disturbingly. The failure
// appears to be benign: alignof(V8) produces a preposterous value: 12
#ifndef _MSC_VER
EXPECT_EQ(alignof(V8), alignof(AlignedCharArrayUnion<V8>));
#endif
EXPECT_EQ(sizeof(char), sizeof(AlignedCharArrayUnion<char>));
EXPECT_EQ(sizeof(char[1]), sizeof(AlignedCharArrayUnion<char[1]>));
EXPECT_EQ(sizeof(char[2]), sizeof(AlignedCharArrayUnion<char[2]>));
EXPECT_EQ(sizeof(char[3]), sizeof(AlignedCharArrayUnion<char[3]>));
EXPECT_EQ(sizeof(char[4]), sizeof(AlignedCharArrayUnion<char[4]>));
EXPECT_EQ(sizeof(char[5]), sizeof(AlignedCharArrayUnion<char[5]>));
EXPECT_EQ(sizeof(char[8]), sizeof(AlignedCharArrayUnion<char[8]>));
EXPECT_EQ(sizeof(char[13]), sizeof(AlignedCharArrayUnion<char[13]>));
EXPECT_EQ(sizeof(char[16]), sizeof(AlignedCharArrayUnion<char[16]>));
EXPECT_EQ(sizeof(char[21]), sizeof(AlignedCharArrayUnion<char[21]>));
EXPECT_EQ(sizeof(char[32]), sizeof(AlignedCharArrayUnion<char[32]>));
EXPECT_EQ(sizeof(short), sizeof(AlignedCharArrayUnion<short>));
EXPECT_EQ(sizeof(int), sizeof(AlignedCharArrayUnion<int>));
EXPECT_EQ(sizeof(long), sizeof(AlignedCharArrayUnion<long>));
EXPECT_EQ(sizeof(long long),
sizeof(AlignedCharArrayUnion<long long>));
EXPECT_EQ(sizeof(float), sizeof(AlignedCharArrayUnion<float>));
EXPECT_EQ(sizeof(double), sizeof(AlignedCharArrayUnion<double>));
EXPECT_EQ(sizeof(long double),
sizeof(AlignedCharArrayUnion<long double>));
EXPECT_EQ(sizeof(void *), sizeof(AlignedCharArrayUnion<void *>));
EXPECT_EQ(sizeof(int *), sizeof(AlignedCharArrayUnion<int *>));
EXPECT_EQ(sizeof(double (*)(double)),
sizeof(AlignedCharArrayUnion<double (*)(double)>));
EXPECT_EQ(sizeof(double (S6::*)()),
sizeof(AlignedCharArrayUnion<double (S6::*)()>));
EXPECT_EQ(sizeof(S1), sizeof(AlignedCharArrayUnion<S1>));
EXPECT_EQ(sizeof(S2), sizeof(AlignedCharArrayUnion<S2>));
EXPECT_EQ(sizeof(S3), sizeof(AlignedCharArrayUnion<S3>));
EXPECT_EQ(sizeof(S4), sizeof(AlignedCharArrayUnion<S4>));
EXPECT_EQ(sizeof(S5), sizeof(AlignedCharArrayUnion<S5>));
EXPECT_EQ(sizeof(S6), sizeof(AlignedCharArrayUnion<S6>));
EXPECT_EQ(sizeof(D1), sizeof(AlignedCharArrayUnion<D1>));
EXPECT_EQ(sizeof(D2), sizeof(AlignedCharArrayUnion<D2>));
EXPECT_EQ(sizeof(D3), sizeof(AlignedCharArrayUnion<D3>));
EXPECT_EQ(sizeof(D4), sizeof(AlignedCharArrayUnion<D4>));
EXPECT_EQ(sizeof(D5), sizeof(AlignedCharArrayUnion<D5>));
EXPECT_EQ(sizeof(D6), sizeof(AlignedCharArrayUnion<D6>));
EXPECT_EQ(sizeof(D7), sizeof(AlignedCharArrayUnion<D7>));
EXPECT_EQ(sizeof(D8), sizeof(AlignedCharArrayUnion<D8>));
EXPECT_EQ(sizeof(D9), sizeof(AlignedCharArrayUnion<D9>));
EXPECT_EQ(sizeof(D9[1]), sizeof(AlignedCharArrayUnion<D9[1]>));
EXPECT_EQ(sizeof(D9[2]), sizeof(AlignedCharArrayUnion<D9[2]>));
EXPECT_EQ(sizeof(D9[3]), sizeof(AlignedCharArrayUnion<D9[3]>));
EXPECT_EQ(sizeof(D9[4]), sizeof(AlignedCharArrayUnion<D9[4]>));
EXPECT_EQ(sizeof(D9[5]), sizeof(AlignedCharArrayUnion<D9[5]>));
EXPECT_EQ(sizeof(D9[8]), sizeof(AlignedCharArrayUnion<D9[8]>));
EXPECT_EQ(sizeof(D9[13]), sizeof(AlignedCharArrayUnion<D9[13]>));
EXPECT_EQ(sizeof(D9[16]), sizeof(AlignedCharArrayUnion<D9[16]>));
EXPECT_EQ(sizeof(D9[21]), sizeof(AlignedCharArrayUnion<D9[21]>));
EXPECT_EQ(sizeof(D9[32]), sizeof(AlignedCharArrayUnion<D9[32]>));
EXPECT_EQ(sizeof(V1), sizeof(AlignedCharArrayUnion<V1>));
EXPECT_EQ(sizeof(V2), sizeof(AlignedCharArrayUnion<V2>));
EXPECT_EQ(sizeof(V3), sizeof(AlignedCharArrayUnion<V3>));
EXPECT_EQ(sizeof(V4), sizeof(AlignedCharArrayUnion<V4>));
EXPECT_EQ(sizeof(V5), sizeof(AlignedCharArrayUnion<V5>));
EXPECT_EQ(sizeof(V6), sizeof(AlignedCharArrayUnion<V6>));
EXPECT_EQ(sizeof(V7), sizeof(AlignedCharArrayUnion<V7>));
// Some versions of MSVC also get this wrong. The failure again appears to be
// benign: sizeof(V8) is only 52 bytes, but our array reserves 56.
#ifndef _MSC_VER
EXPECT_EQ(sizeof(V8), sizeof(AlignedCharArrayUnion<V8>));
#endif
EXPECT_EQ(1u, (alignof(AlignedCharArray<1, 1>)));
EXPECT_EQ(2u, (alignof(AlignedCharArray<2, 1>)));
EXPECT_EQ(4u, (alignof(AlignedCharArray<4, 1>)));
EXPECT_EQ(8u, (alignof(AlignedCharArray<8, 1>)));
EXPECT_EQ(16u, (alignof(AlignedCharArray<16, 1>)));
EXPECT_EQ(1u, sizeof(AlignedCharArray<1, 1>));
EXPECT_EQ(7u, sizeof(AlignedCharArray<1, 7>));
EXPECT_EQ(2u, sizeof(AlignedCharArray<2, 2>));
EXPECT_EQ(16u, sizeof(AlignedCharArray<2, 16>));
}
} // end anonymous namespace

View File

@ -0,0 +1,188 @@
//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/Allocator.h"
#include "gtest/gtest.h"
#include <cstdlib>
using namespace llvm;
namespace {
TEST(AllocatorTest, Basics) {
BumpPtrAllocator Alloc;
int *a = (int*)Alloc.Allocate(sizeof(int), alignof(int));
int *b = (int*)Alloc.Allocate(sizeof(int) * 10, alignof(int));
int *c = (int*)Alloc.Allocate(sizeof(int), alignof(int));
*a = 1;
b[0] = 2;
b[9] = 2;
*c = 3;
EXPECT_EQ(1, *a);
EXPECT_EQ(2, b[0]);
EXPECT_EQ(2, b[9]);
EXPECT_EQ(3, *c);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
BumpPtrAllocator Alloc2 = std::move(Alloc);
EXPECT_EQ(0U, Alloc.GetNumSlabs());
EXPECT_EQ(1U, Alloc2.GetNumSlabs());
// Make sure the old pointers still work. These are especially interesting
// under ASan or Valgrind.
EXPECT_EQ(1, *a);
EXPECT_EQ(2, b[0]);
EXPECT_EQ(2, b[9]);
EXPECT_EQ(3, *c);
Alloc = std::move(Alloc2);
EXPECT_EQ(0U, Alloc2.GetNumSlabs());
EXPECT_EQ(1U, Alloc.GetNumSlabs());
}
// Allocate enough bytes to create three slabs.
TEST(AllocatorTest, ThreeSlabs) {
BumpPtrAllocator Alloc;
Alloc.Allocate(3000, 1);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
Alloc.Allocate(3000, 1);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
Alloc.Allocate(3000, 1);
EXPECT_EQ(3U, Alloc.GetNumSlabs());
}
// Allocate enough bytes to create two slabs, reset the allocator, and do it
// again.
TEST(AllocatorTest, TestReset) {
BumpPtrAllocator Alloc;
// Allocate something larger than the SizeThreshold=4096.
(void)Alloc.Allocate(5000, 1);
Alloc.Reset();
// Calling Reset should free all CustomSizedSlabs.
EXPECT_EQ(0u, Alloc.GetNumSlabs());
Alloc.Allocate(3000, 1);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
Alloc.Allocate(3000, 1);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
Alloc.Reset();
EXPECT_EQ(1U, Alloc.GetNumSlabs());
Alloc.Allocate(3000, 1);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
Alloc.Allocate(3000, 1);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
}
// Test some allocations at varying alignments.
TEST(AllocatorTest, TestAlignment) {
BumpPtrAllocator Alloc;
uintptr_t a;
a = (uintptr_t)Alloc.Allocate(1, 2);
EXPECT_EQ(0U, a & 1);
a = (uintptr_t)Alloc.Allocate(1, 4);
EXPECT_EQ(0U, a & 3);
a = (uintptr_t)Alloc.Allocate(1, 8);
EXPECT_EQ(0U, a & 7);
a = (uintptr_t)Alloc.Allocate(1, 16);
EXPECT_EQ(0U, a & 15);
a = (uintptr_t)Alloc.Allocate(1, 32);
EXPECT_EQ(0U, a & 31);
a = (uintptr_t)Alloc.Allocate(1, 64);
EXPECT_EQ(0U, a & 63);
a = (uintptr_t)Alloc.Allocate(1, 128);
EXPECT_EQ(0U, a & 127);
}
// Test allocating just over the slab size. This tests a bug where before the
// allocator incorrectly calculated the buffer end pointer.
TEST(AllocatorTest, TestOverflow) {
BumpPtrAllocator Alloc;
// Fill the slab right up until the end pointer.
Alloc.Allocate(4096, 1);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
// If we don't allocate a new slab, then we will have overflowed.
Alloc.Allocate(1, 1);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
}
// Test allocating with a size larger than the initial slab size.
TEST(AllocatorTest, TestSmallSlabSize) {
BumpPtrAllocator Alloc;
Alloc.Allocate(8000, 1);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
}
// Test requesting alignment that goes past the end of the current slab.
TEST(AllocatorTest, TestAlignmentPastSlab) {
BumpPtrAllocator Alloc;
Alloc.Allocate(4095, 1);
// Aligning the current slab pointer is likely to move it past the end of the
// slab, which would confuse any unsigned comparisons with the difference of
// the end pointer and the aligned pointer.
Alloc.Allocate(1024, 8192);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
}
// Mock slab allocator that returns slabs aligned on 4096 bytes. There is no
// easy portable way to do this, so this is kind of a hack.
class MockSlabAllocator {
static size_t LastSlabSize;
public:
~MockSlabAllocator() { }
void *Allocate(size_t Size, size_t /*Alignment*/) {
// Allocate space for the alignment, the slab, and a void* that goes right
// before the slab.
size_t Alignment = 4096;
void *MemBase = malloc(Size + Alignment - 1 + sizeof(void*));
// Find the slab start.
void *Slab = (void *)alignAddr((char*)MemBase + sizeof(void *), Alignment);
// Hold a pointer to the base so we can free the whole malloced block.
((void**)Slab)[-1] = MemBase;
LastSlabSize = Size;
return Slab;
}
void Deallocate(void *Slab, size_t Size) {
free(((void**)Slab)[-1]);
}
static size_t GetLastSlabSize() { return LastSlabSize; }
};
size_t MockSlabAllocator::LastSlabSize = 0;
// Allocate a large-ish block with a really large alignment so that the
// allocator will think that it has space, but after it does the alignment it
// will not.
TEST(AllocatorTest, TestBigAlignment) {
BumpPtrAllocatorImpl<MockSlabAllocator> Alloc;
// First allocate a tiny bit to ensure we have to re-align things.
(void)Alloc.Allocate(1, 1);
// Now the big chunk with a big alignment.
(void)Alloc.Allocate(3000, 2048);
// We test that the last slab size is not the default 4096 byte slab, but
// rather a custom sized slab that is larger.
EXPECT_GT(MockSlabAllocator::GetLastSlabSize(), 4096u);
}
} // anonymous namespace

View File

@ -0,0 +1,109 @@
//===--- unittest/Support/ArrayRecyclerTest.cpp ---------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/ArrayRecycler.h"
#include "llvm/Support/Allocator.h"
#include "gtest/gtest.h"
#include <cstdlib>
using namespace llvm;
namespace {
struct Object {
int Num;
Object *Other;
};
typedef ArrayRecycler<Object> ARO;
TEST(ArrayRecyclerTest, Capacity) {
// Capacity size should never be 0.
ARO::Capacity Cap = ARO::Capacity::get(0);
EXPECT_LT(0u, Cap.getSize());
size_t PrevSize = Cap.getSize();
for (unsigned N = 1; N != 100; ++N) {
Cap = ARO::Capacity::get(N);
EXPECT_LE(N, Cap.getSize());
if (PrevSize >= N)
EXPECT_EQ(PrevSize, Cap.getSize());
else
EXPECT_LT(PrevSize, Cap.getSize());
PrevSize = Cap.getSize();
}
// Check that the buckets are monotonically increasing.
Cap = ARO::Capacity::get(0);
PrevSize = Cap.getSize();
for (unsigned N = 0; N != 20; ++N) {
Cap = Cap.getNext();
EXPECT_LT(PrevSize, Cap.getSize());
PrevSize = Cap.getSize();
}
}
TEST(ArrayRecyclerTest, Basics) {
BumpPtrAllocator Allocator;
ArrayRecycler<Object> DUT;
ARO::Capacity Cap = ARO::Capacity::get(8);
Object *A1 = DUT.allocate(Cap, Allocator);
A1[0].Num = 21;
A1[7].Num = 17;
Object *A2 = DUT.allocate(Cap, Allocator);
A2[0].Num = 121;
A2[7].Num = 117;
Object *A3 = DUT.allocate(Cap, Allocator);
A3[0].Num = 221;
A3[7].Num = 217;
EXPECT_EQ(21, A1[0].Num);
EXPECT_EQ(17, A1[7].Num);
EXPECT_EQ(121, A2[0].Num);
EXPECT_EQ(117, A2[7].Num);
EXPECT_EQ(221, A3[0].Num);
EXPECT_EQ(217, A3[7].Num);
DUT.deallocate(Cap, A2);
// Check that deallocation didn't clobber anything.
EXPECT_EQ(21, A1[0].Num);
EXPECT_EQ(17, A1[7].Num);
EXPECT_EQ(221, A3[0].Num);
EXPECT_EQ(217, A3[7].Num);
// Verify recycling.
Object *A2x = DUT.allocate(Cap, Allocator);
EXPECT_EQ(A2, A2x);
DUT.deallocate(Cap, A2x);
DUT.deallocate(Cap, A1);
DUT.deallocate(Cap, A3);
// Objects are not required to be recycled in reverse deallocation order, but
// that is what the current implementation does.
Object *A3x = DUT.allocate(Cap, Allocator);
EXPECT_EQ(A3, A3x);
Object *A1x = DUT.allocate(Cap, Allocator);
EXPECT_EQ(A1, A1x);
Object *A2y = DUT.allocate(Cap, Allocator);
EXPECT_EQ(A2, A2y);
// Back to allocation from the BumpPtrAllocator.
Object *A4 = DUT.allocate(Cap, Allocator);
EXPECT_NE(A1, A4);
EXPECT_NE(A2, A4);
EXPECT_NE(A3, A4);
DUT.clear(Allocator);
}
} // end anonymous namespace

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
//===- unittests/Support/BlockFrequencyTest.cpp - BlockFrequency tests ----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/DataTypes.h"
#include "gtest/gtest.h"
#include <climits>
using namespace llvm;
namespace {
TEST(BlockFrequencyTest, OneToZero) {
BlockFrequency Freq(1);
BranchProbability Prob(UINT32_MAX / 3, UINT32_MAX);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 0u);
Freq = BlockFrequency(1);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 0u);
}
TEST(BlockFrequencyTest, OneToOne) {
BlockFrequency Freq(1);
BranchProbability Prob(UINT32_MAX, UINT32_MAX);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 1u);
Freq = BlockFrequency(1);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 1u);
}
TEST(BlockFrequencyTest, ThreeToOne) {
BlockFrequency Freq(3);
BranchProbability Prob(3000000, 9000000);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 1u);
Freq = BlockFrequency(3);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 1u);
}
TEST(BlockFrequencyTest, MaxToHalfMax) {
BlockFrequency Freq(UINT64_MAX);
BranchProbability Prob(UINT32_MAX / 2, UINT32_MAX);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 9223372036854775807ULL);
Freq = BlockFrequency(UINT64_MAX);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), 9223372036854775807ULL);
}
TEST(BlockFrequencyTest, BigToBig) {
const uint64_t Big = 387246523487234346LL;
const uint32_t P = 123456789;
BlockFrequency Freq(Big);
BranchProbability Prob(P, P);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), Big);
Freq = BlockFrequency(Big);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), Big);
}
TEST(BlockFrequencyTest, MaxToMax) {
BlockFrequency Freq(UINT64_MAX);
BranchProbability Prob(UINT32_MAX, UINT32_MAX);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);
// This additionally makes sure if we have a value equal to our saturating
// value, we do not signal saturation if the result equals said value, but
// saturating does not occur.
Freq = BlockFrequency(UINT64_MAX);
Freq *= Prob;
EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);
}
TEST(BlockFrequencyTest, Subtract) {
BlockFrequency Freq1(0), Freq2(1);
EXPECT_EQ((Freq1 - Freq2).getFrequency(), 0u);
EXPECT_EQ((Freq2 - Freq1).getFrequency(), 1u);
}
TEST(BlockFrequency, Divide) {
BlockFrequency Freq(0x3333333333333333ULL);
Freq /= BranchProbability(1, 2);
EXPECT_EQ(Freq.getFrequency(), 0x6666666666666666ULL);
}
TEST(BlockFrequencyTest, Saturate) {
BlockFrequency Freq(0x3333333333333333ULL);
Freq /= BranchProbability(100, 300);
EXPECT_EQ(Freq.getFrequency(), 0x9999999866666668ULL);
Freq /= BranchProbability(1, 2);
EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);
Freq = 0x1000000000000000ULL;
Freq /= BranchProbability(10000, 170000);
EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);
// Try to cheat the multiplication overflow check.
Freq = 0x00000001f0000001ull;
Freq /= BranchProbability(1000, 0xf000000f);
EXPECT_EQ(33527736066704712ULL, Freq.getFrequency());
}
TEST(BlockFrequencyTest, SaturatingRightShift) {
BlockFrequency Freq(0x10080ULL);
Freq >>= 2;
EXPECT_EQ(Freq.getFrequency(), 0x4020ULL);
Freq >>= 20;
EXPECT_EQ(Freq.getFrequency(), 0x1ULL);
}
}

View File

@ -0,0 +1,406 @@
//===- unittest/Support/BranchProbabilityTest.cpp - BranchProbability tests -=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace llvm {
void PrintTo(BranchProbability P, ::std::ostream *os) {
*os << P.getNumerator() << "/" << P.getDenominator();
}
}
namespace {
typedef BranchProbability BP;
TEST(BranchProbabilityTest, Accessors) {
EXPECT_EQ(306783378u, BP(1, 7).getNumerator());
EXPECT_EQ(1u << 31, BP(1, 7).getDenominator());
EXPECT_EQ(0u, BP::getZero().getNumerator());
EXPECT_EQ(1u << 31, BP::getZero().getDenominator());
EXPECT_EQ(1u << 31, BP::getOne().getNumerator());
EXPECT_EQ(1u << 31, BP::getOne().getDenominator());
}
TEST(BranchProbabilityTest, Operators) {
EXPECT_TRUE(BP(1, 7) < BP(2, 7));
EXPECT_TRUE(BP(1, 7) < BP(1, 4));
EXPECT_TRUE(BP(5, 7) < BP(3, 4));
EXPECT_FALSE(BP(1, 7) < BP(1, 7));
EXPECT_FALSE(BP(1, 7) < BP(2, 14));
EXPECT_FALSE(BP(4, 7) < BP(1, 2));
EXPECT_FALSE(BP(4, 7) < BP(3, 7));
EXPECT_FALSE(BP(1, 7) > BP(2, 7));
EXPECT_FALSE(BP(1, 7) > BP(1, 4));
EXPECT_FALSE(BP(5, 7) > BP(3, 4));
EXPECT_FALSE(BP(1, 7) > BP(1, 7));
EXPECT_FALSE(BP(1, 7) > BP(2, 14));
EXPECT_TRUE(BP(4, 7) > BP(1, 2));
EXPECT_TRUE(BP(4, 7) > BP(3, 7));
EXPECT_TRUE(BP(1, 7) <= BP(2, 7));
EXPECT_TRUE(BP(1, 7) <= BP(1, 4));
EXPECT_TRUE(BP(5, 7) <= BP(3, 4));
EXPECT_TRUE(BP(1, 7) <= BP(1, 7));
EXPECT_TRUE(BP(1, 7) <= BP(2, 14));
EXPECT_FALSE(BP(4, 7) <= BP(1, 2));
EXPECT_FALSE(BP(4, 7) <= BP(3, 7));
EXPECT_FALSE(BP(1, 7) >= BP(2, 7));
EXPECT_FALSE(BP(1, 7) >= BP(1, 4));
EXPECT_FALSE(BP(5, 7) >= BP(3, 4));
EXPECT_TRUE(BP(1, 7) >= BP(1, 7));
EXPECT_TRUE(BP(1, 7) >= BP(2, 14));
EXPECT_TRUE(BP(4, 7) >= BP(1, 2));
EXPECT_TRUE(BP(4, 7) >= BP(3, 7));
EXPECT_FALSE(BP(1, 7) == BP(2, 7));
EXPECT_FALSE(BP(1, 7) == BP(1, 4));
EXPECT_FALSE(BP(5, 7) == BP(3, 4));
EXPECT_TRUE(BP(1, 7) == BP(1, 7));
EXPECT_TRUE(BP(1, 7) == BP(2, 14));
EXPECT_FALSE(BP(4, 7) == BP(1, 2));
EXPECT_FALSE(BP(4, 7) == BP(3, 7));
EXPECT_TRUE(BP(1, 7) != BP(2, 7));
EXPECT_TRUE(BP(1, 7) != BP(1, 4));
EXPECT_TRUE(BP(5, 7) != BP(3, 4));
EXPECT_FALSE(BP(1, 7) != BP(1, 7));
EXPECT_FALSE(BP(1, 7) != BP(2, 14));
EXPECT_TRUE(BP(4, 7) != BP(1, 2));
EXPECT_TRUE(BP(4, 7) != BP(3, 7));
EXPECT_TRUE(BP(1, 7) == BP(2, 14));
EXPECT_TRUE(BP(1, 7) == BP(3, 21));
EXPECT_TRUE(BP(5, 7) == BP(25, 35));
EXPECT_TRUE(BP(99999998, 100000000) < BP(99999999, 100000000));
EXPECT_TRUE(BP(4, 8) == BP(400000000, 800000000));
}
TEST(BranchProbabilityTest, MoreOperators) {
BP A(4, 5);
BP B(4U << 29, 5U << 29);
BP C(3, 4);
EXPECT_TRUE(A == B);
EXPECT_FALSE(A != B);
EXPECT_FALSE(A < B);
EXPECT_FALSE(A > B);
EXPECT_TRUE(A <= B);
EXPECT_TRUE(A >= B);
EXPECT_FALSE(B == C);
EXPECT_TRUE(B != C);
EXPECT_FALSE(B < C);
EXPECT_TRUE(B > C);
EXPECT_FALSE(B <= C);
EXPECT_TRUE(B >= C);
BP BigZero(0, UINT32_MAX);
BP BigOne(UINT32_MAX, UINT32_MAX);
EXPECT_FALSE(BigZero == BigOne);
EXPECT_TRUE(BigZero != BigOne);
EXPECT_TRUE(BigZero < BigOne);
EXPECT_FALSE(BigZero > BigOne);
EXPECT_TRUE(BigZero <= BigOne);
EXPECT_FALSE(BigZero >= BigOne);
}
TEST(BranchProbabilityTest, ArithmeticOperators) {
BP Z(0, 1);
BP O(1, 1);
BP H(1, 2);
BP Q(1, 4);
BP Q3(3, 4);
EXPECT_EQ(Z + O, O);
EXPECT_EQ(H + Z, H);
EXPECT_EQ(H + H, O);
EXPECT_EQ(Q + H, Q3);
EXPECT_EQ(Q + Q3, O);
EXPECT_EQ(H + Q3, O);
EXPECT_EQ(Q3 + Q3, O);
EXPECT_EQ(Z - O, Z);
EXPECT_EQ(O - Z, O);
EXPECT_EQ(O - H, H);
EXPECT_EQ(O - Q, Q3);
EXPECT_EQ(Q3 - H, Q);
EXPECT_EQ(Q - H, Z);
EXPECT_EQ(Q - Q3, Z);
EXPECT_EQ(Z * O, Z);
EXPECT_EQ(H * H, Q);
EXPECT_EQ(Q * O, Q);
EXPECT_EQ(O * O, O);
EXPECT_EQ(Z * Z, Z);
EXPECT_EQ(Z * 3, Z);
EXPECT_EQ(Q * 3, Q3);
EXPECT_EQ(H * 3, O);
EXPECT_EQ(Q3 * 2, O);
EXPECT_EQ(O * UINT32_MAX, O);
EXPECT_EQ(Z / 4, Z);
EXPECT_EQ(O / 4, Q);
EXPECT_EQ(Q3 / 3, Q);
EXPECT_EQ(H / 2, Q);
EXPECT_EQ(O / 2, H);
EXPECT_EQ(H / UINT32_MAX, Z);
BP Min(1, 1u << 31);
EXPECT_EQ(O / UINT32_MAX, Z);
EXPECT_EQ(Min * UINT32_MAX, O);
}
TEST(BranchProbabilityTest, getCompl) {
EXPECT_EQ(BP(5, 7), BP(2, 7).getCompl());
EXPECT_EQ(BP(2, 7), BP(5, 7).getCompl());
EXPECT_EQ(BP::getZero(), BP(7, 7).getCompl());
EXPECT_EQ(BP::getOne(), BP(0, 7).getCompl());
}
TEST(BranchProbabilityTest, scale) {
// Multiply by 1.0.
EXPECT_EQ(UINT64_MAX, BP(1, 1).scale(UINT64_MAX));
EXPECT_EQ(UINT64_MAX, BP(7, 7).scale(UINT64_MAX));
EXPECT_EQ(UINT32_MAX, BP(1, 1).scale(UINT32_MAX));
EXPECT_EQ(UINT32_MAX, BP(7, 7).scale(UINT32_MAX));
EXPECT_EQ(0u, BP(1, 1).scale(0));
EXPECT_EQ(0u, BP(7, 7).scale(0));
// Multiply by 0.0.
EXPECT_EQ(0u, BP(0, 1).scale(UINT64_MAX));
EXPECT_EQ(0u, BP(0, 1).scale(UINT64_MAX));
EXPECT_EQ(0u, BP(0, 1).scale(0));
auto Two63 = UINT64_C(1) << 63;
auto Two31 = UINT64_C(1) << 31;
// Multiply by 0.5.
EXPECT_EQ(Two63 - 1, BP(1, 2).scale(UINT64_MAX));
// Big fractions.
EXPECT_EQ(1u, BP(Two31, UINT32_MAX).scale(2));
EXPECT_EQ(Two31, BP(Two31, UINT32_MAX).scale(Two31 * 2));
EXPECT_EQ(9223372036854775807ULL, BP(Two31, UINT32_MAX).scale(UINT64_MAX));
// High precision.
EXPECT_EQ(UINT64_C(9223372045444710399),
BP(Two31 + 1, UINT32_MAX - 2).scale(UINT64_MAX));
}
TEST(BranchProbabilityTest, scaleByInverse) {
// Divide by 1.0.
EXPECT_EQ(UINT64_MAX, BP(1, 1).scaleByInverse(UINT64_MAX));
EXPECT_EQ(UINT64_MAX, BP(7, 7).scaleByInverse(UINT64_MAX));
EXPECT_EQ(UINT32_MAX, BP(1, 1).scaleByInverse(UINT32_MAX));
EXPECT_EQ(UINT32_MAX, BP(7, 7).scaleByInverse(UINT32_MAX));
EXPECT_EQ(0u, BP(1, 1).scaleByInverse(0));
EXPECT_EQ(0u, BP(7, 7).scaleByInverse(0));
auto MAX_DENOMINATOR = BP::getDenominator();
// Divide by something very small.
EXPECT_EQ(UINT64_MAX, BP(1, UINT32_MAX).scaleByInverse(UINT64_MAX));
EXPECT_EQ(uint64_t(UINT32_MAX) * MAX_DENOMINATOR,
BP(1, MAX_DENOMINATOR).scaleByInverse(UINT32_MAX));
EXPECT_EQ(MAX_DENOMINATOR, BP(1, MAX_DENOMINATOR).scaleByInverse(1));
auto Two63 = UINT64_C(1) << 63;
auto Two31 = UINT64_C(1) << 31;
// Divide by 0.5.
EXPECT_EQ(UINT64_MAX - 1, BP(1, 2).scaleByInverse(Two63 - 1));
EXPECT_EQ(UINT64_MAX, BP(1, 2).scaleByInverse(Two63));
// Big fractions.
EXPECT_EQ(2u, BP(Two31, UINT32_MAX).scaleByInverse(1));
EXPECT_EQ(2u, BP(Two31 - 1, UINT32_MAX).scaleByInverse(1));
EXPECT_EQ(Two31 * 2, BP(Two31, UINT32_MAX).scaleByInverse(Two31));
EXPECT_EQ(Two31 * 2, BP(Two31 - 1, UINT32_MAX).scaleByInverse(Two31));
EXPECT_EQ(UINT64_MAX, BP(Two31, UINT32_MAX).scaleByInverse(Two63 + Two31));
// High precision. The exact answers to these are close to the successors of
// the floor. If we were rounding, these would round up.
EXPECT_EQ(UINT64_C(18446744060824649767),
BP(Two31 + 2, UINT32_MAX - 2)
.scaleByInverse(UINT64_C(9223372047592194056)));
EXPECT_EQ(UINT64_C(18446744060824649739),
BP(Two31 + 1, UINT32_MAX).scaleByInverse(Two63 + Two31));
}
TEST(BranchProbabilityTest, scaleBruteForce) {
struct {
uint64_t Num;
uint32_t Prob[2];
uint64_t Result;
} Tests[] = {
// Data for scaling that results in <= 64 bit division.
{ 0x1423e2a50ULL, { 0x64819521, 0x7765dd13 }, 0x10f418888ULL },
{ 0x35ef14ceULL, { 0x28ade3c7, 0x304532ae }, 0x2d73c33bULL },
{ 0xd03dbfbe24ULL, { 0x790079, 0xe419f3 }, 0x6e776fc2c4ULL },
{ 0x21d67410bULL, { 0x302a9dc2, 0x3ddb4442 }, 0x1a5948fd4ULL },
{ 0x8664aeadULL, { 0x3d523513, 0x403523b1 }, 0x805a04cfULL },
{ 0x201db0cf4ULL, { 0x35112a7b, 0x79fc0c74 }, 0xdf8b07f8ULL },
{ 0x13f1e4430aULL, { 0x21c92bf, 0x21e63aae }, 0x13e0cba26ULL },
{ 0x16c83229ULL, { 0x3793f66f, 0x53180dea }, 0xf3ce7b6ULL },
{ 0xc62415be8ULL, { 0x9cc4a63, 0x4327ae9b }, 0x1ce8b71c1ULL },
{ 0x6fac5e434ULL, { 0xe5f9170, 0x1115e10b }, 0x5df23dd4cULL },
{ 0x1929375f2ULL, { 0x3a851375, 0x76c08456 }, 0xc662b083ULL },
{ 0x243c89db6ULL, { 0x354ebfc0, 0x450ef197 }, 0x1bf8c1663ULL },
{ 0x310e9b31aULL, { 0x1b1b8acf, 0x2d3629f0 }, 0x1d69c93f9ULL },
{ 0xa1fae921dULL, { 0xa7a098c, 0x10469f44 }, 0x684413d6eULL },
{ 0xc1582d957ULL, { 0x498e061, 0x59856bc }, 0x9edc5f4ecULL },
{ 0x57cfee75ULL, { 0x1d061dc3, 0x7c8bfc17 }, 0x1476a220ULL },
{ 0x139220080ULL, { 0x294a6c71, 0x2a2b07c9 }, 0x1329e1c75ULL },
{ 0x1665d353cULL, { 0x7080db5, 0xde0d75c }, 0xb590d9faULL },
{ 0xe8f14541ULL, { 0x5188e8b2, 0x736527ef }, 0xa4971be5ULL },
{ 0x2f4775f29ULL, { 0x254ef0fe, 0x435fcf50 }, 0x1a2e449c1ULL },
{ 0x27b85d8d7ULL, { 0x304c8220, 0x5de678f2 }, 0x146e3befbULL },
{ 0x1d362e36bULL, { 0x36c85b12, 0x37a66f55 }, 0x1cc19b8e7ULL },
{ 0x155fd48c7ULL, { 0xf5894d, 0x1256108 }, 0x11e383604ULL },
{ 0xb5db2d15ULL, { 0x39bb26c5, 0x5bdcda3e }, 0x72499259ULL },
{ 0x153990298ULL, { 0x48921c09, 0x706eb817 }, 0xdb3268e7ULL },
{ 0x28a7c3ed7ULL, { 0x1f776fd7, 0x349f7a70 }, 0x184f73ae2ULL },
{ 0x724dbeabULL, { 0x1bd149f5, 0x253a085e }, 0x5569c0b3ULL },
{ 0xd8f0c513ULL, { 0x18c8cc4c, 0x1b72bad0 }, 0xc3e30642ULL },
{ 0x17ce3dcbULL, { 0x1e4c6260, 0x233b359e }, 0x1478f4afULL },
{ 0x1ce036ce0ULL, { 0x29e3c8af, 0x5318dd4a }, 0xe8e76195ULL },
{ 0x1473ae2aULL, { 0x29b897ba, 0x2be29378 }, 0x13718185ULL },
{ 0x1dd41aa68ULL, { 0x3d0a4441, 0x5a0e8f12 }, 0x1437b6bbfULL },
{ 0x1b49e4a53ULL, { 0x3430c1fe, 0x5a204aed }, 0xfcd6852fULL },
{ 0x217941b19ULL, { 0x12ced2bd, 0x21b68310 }, 0x12aca65b1ULL },
{ 0xac6a4dc8ULL, { 0x3ed68da8, 0x6fdca34c }, 0x60da926dULL },
{ 0x1c503a4e7ULL, { 0xfcbbd32, 0x11e48d17 }, 0x18fec7d37ULL },
{ 0x1c885855ULL, { 0x213e919d, 0x25941897 }, 0x193de742ULL },
{ 0x29b9c168eULL, { 0x2b644aea, 0x45725ee7 }, 0x1a122e5d4ULL },
{ 0x806a33f2ULL, { 0x30a80a23, 0x5063733a }, 0x4db9a264ULL },
{ 0x282afc96bULL, { 0x143ae554, 0x1a9863ff }, 0x1e8de5204ULL },
// Data for scaling that results in > 64 bit division.
{ 0x23ca5f2f672ca41cULL, { 0xecbc641, 0x111373f7 }, 0x1f0301e5c76869c6ULL },
{ 0x5e4f2468142265e3ULL, { 0x1ddf5837, 0x32189233 }, 0x383ca7bad6053ac9ULL },
{ 0x277a1a6f6b266bf6ULL, { 0x415d81a8, 0x61eb5e1e }, 0x1a5a3e1d1c9e8540ULL },
{ 0x1bdbb49a237035cbULL, { 0xea5bf17, 0x1d25ffb3 }, 0xdffc51c5cb51cf1ULL },
{ 0x2bce6d29b64fb8ULL, { 0x3bfd5631, 0x7525c9bb }, 0x166ebedd9581fdULL },
{ 0x3a02116103df5013ULL, { 0x2ee18a83, 0x3299aea8 }, 0x35be89227276f105ULL },
{ 0x7b5762390799b18cULL, { 0x12f8e5b9, 0x2563bcd4 }, 0x3e960077695655a3ULL },
{ 0x69cfd72537021579ULL, { 0x4c35f468, 0x6a40feee }, 0x4be4cb38695a4f30ULL },
{ 0x49dfdf835120f1c1ULL, { 0x8cb3759, 0x559eb891 }, 0x79663f6e3c8d8f6ULL },
{ 0x74b5be5c27676381ULL, { 0x47e4c5e0, 0x7c7b19ff }, 0x4367d2dfb22b3265ULL },
{ 0x4f50f97075e7f431ULL, { 0x9a50a17, 0x11cd1185 }, 0x2af952b30374f382ULL },
{ 0x2f8b0d712e393be4ULL, { 0x1487e386, 0x15aa356e }, 0x2d0df3649b2b19fcULL },
{ 0x224c1c75999d3deULL, { 0x3b2df0ea, 0x4523b100 }, 0x1d5b481d160dd8bULL },
{ 0x2bcbcea22a399a76ULL, { 0x28b58212, 0x48dd013e }, 0x187814d0610c8a56ULL },
{ 0x1dbfca91257cb2d1ULL, { 0x1a8c04d9, 0x5e92502c }, 0x859cf7d19e83ad0ULL },
{ 0x7f20039b57cda935ULL, { 0xeccf651, 0x323f476e }, 0x25720cd9054634bdULL },
{ 0x40512c6a586aa087ULL, { 0x113b0423, 0x398c9eab }, 0x1341c03dbb662054ULL },
{ 0x63d802693f050a11ULL, { 0xf50cdd6, 0xfce2a44 }, 0x60c0177b667a4feaULL },
{ 0x2d956b422838de77ULL, { 0xb2d345b, 0x1321e557 }, 0x1aa0ed16b094575cULL },
{ 0x5a1cdf0c1657bc91ULL, { 0x1d77bb0c, 0x1f991ff1 }, 0x54097ee9907290eaULL },
{ 0x3801b26d7e00176bULL, { 0xeed25da, 0x1a819d8b }, 0x1f89e96a616b9abeULL },
{ 0x37655e74338e1e45ULL, { 0x300e170a, 0x5a1595fe }, 0x1d8cfb55ff6a6dbcULL },
{ 0x7b38703f2a84e6ULL, { 0x66d9053, 0xc79b6b9 }, 0x3f7d4c91b9afb9ULL },
{ 0x2245063c0acb3215ULL, { 0x30ce2f5b, 0x610e7271 }, 0x113b916455fe2560ULL },
{ 0x6bc195877b7b8a7eULL, { 0x392004aa, 0x4a24e60c }, 0x530594fabfc81cc3ULL },
{ 0x40a3fde23c7b43dbULL, { 0x4e712195, 0x6553e56e }, 0x320a799bc205c78dULL },
{ 0x1d3dfc2866fbccbaULL, { 0x5075b517, 0x5fc42245 }, 0x18917f00745cb781ULL },
{ 0x19aeb14045a61121ULL, { 0x1bf6edec, 0x707e2f4b }, 0x6626672aa2ba10aULL },
{ 0x44ff90486c531e9fULL, { 0x66598a, 0x8a90dc }, 0x32f6f2b097001598ULL },
{ 0x3f3e7121092c5bcbULL, { 0x1c754df7, 0x5951a1b9 }, 0x14267f50d4971583ULL },
{ 0x60e2dafb7e50a67eULL, { 0x4d96c66e, 0x65bd878d }, 0x49e317155d75e883ULL },
{ 0x656286667e0e6e29ULL, { 0x9d971a2, 0xacda23b }, 0x5c6ee3159e1deac3ULL },
{ 0x1114e0974255d507ULL, { 0x1c693, 0x2d6ff }, 0xaae42e4be5f9f8dULL },
{ 0x508c8baf3a70ff5aULL, { 0x3b26b779, 0x6ad78745 }, 0x2c983876178ed5b1ULL },
{ 0x5b47bc666bf1f9cfULL, { 0x10a87ed6, 0x187d358a }, 0x3e1767153bea720aULL },
{ 0x50954e3744460395ULL, { 0x7a42263, 0xcdaa048 }, 0x2fe739f0944a023cULL },
{ 0x20020b406550dd8fULL, { 0x3318539, 0x42eead0 }, 0x186f326307c0d985ULL },
{ 0x5bcb0b872439ffd5ULL, { 0x6f61fb2, 0x9af7344 }, 0x41fa1e3c47f0f80dULL },
{ 0x7a670f365db87a53ULL, { 0x417e102, 0x3bb54c67 }, 0x8642a551d0f41b0ULL },
{ 0x1ef0db1e7bab1cd0ULL, { 0x2b60cf38, 0x4188f78f }, 0x147ae0d63fc0575aULL }
};
for (const auto &T : Tests) {
EXPECT_EQ(T.Result, BP(T.Prob[0], T.Prob[1]).scale(T.Num));
}
}
TEST(BranchProbabilityTest, NormalizeProbabilities) {
const auto UnknownProb = BranchProbability::getUnknown();
{
SmallVector<BranchProbability, 2> Probs{{0, 1}, {0, 1}};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[0].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[1].getNumerator());
}
{
SmallVector<BranchProbability, 2> Probs{{0, 1}, {1, 1}};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(0u, Probs[0].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator(), Probs[1].getNumerator());
}
{
SmallVector<BranchProbability, 2> Probs{{1, 100}, {1, 100}};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[0].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[1].getNumerator());
}
{
SmallVector<BranchProbability, 2> Probs{{1, 1}, {1, 1}};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[0].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[1].getNumerator());
}
{
SmallVector<BranchProbability, 3> Probs{{1, 1}, {1, 1}, {1, 1}};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
Probs[0].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
Probs[1].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
Probs[2].getNumerator());
}
{
SmallVector<BranchProbability, 2> Probs{{0, 1}, UnknownProb};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(0U, Probs[0].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator(), Probs[1].getNumerator());
}
{
SmallVector<BranchProbability, 2> Probs{{1, 1}, UnknownProb};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(BranchProbability::getDenominator(), Probs[0].getNumerator());
EXPECT_EQ(0U, Probs[1].getNumerator());
}
{
SmallVector<BranchProbability, 2> Probs{{1, 2}, UnknownProb};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[0].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[1].getNumerator());
}
{
SmallVector<BranchProbability, 4> Probs{
{1, 2}, {1, 2}, {1, 2}, UnknownProb};
BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
Probs[0].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
Probs[1].getNumerator());
EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
Probs[2].getNumerator());
EXPECT_EQ(0U, Probs[3].getNumerator());
}
}
}

View File

@ -0,0 +1,81 @@
set(LLVM_LINK_COMPONENTS
Support
)
add_llvm_unittest(SupportTests
AlignOfTest.cpp
AllocatorTest.cpp
ARMAttributeParser.cpp
ArrayRecyclerTest.cpp
BinaryStreamTest.cpp
BlockFrequencyTest.cpp
BranchProbabilityTest.cpp
CachePruningTest.cpp
CrashRecoveryTest.cpp
Casting.cpp
Chrono.cpp
CommandLineTest.cpp
CompressionTest.cpp
ConvertUTFTest.cpp
DataExtractorTest.cpp
DebugTest.cpp
EndianStreamTest.cpp
EndianTest.cpp
ErrnoTest.cpp
ErrorOrTest.cpp
ErrorTest.cpp
FileOutputBufferTest.cpp
FormatVariadicTest.cpp
GlobPatternTest.cpp
Host.cpp
LEB128Test.cpp
LineIteratorTest.cpp
LockFileManagerTest.cpp
MD5Test.cpp
ManagedStatic.cpp
MathExtrasTest.cpp
MemoryBufferTest.cpp
MemoryTest.cpp
NativeFormatTests.cpp
ParallelTest.cpp
Path.cpp
ProcessTest.cpp
ProgramTest.cpp
RegexTest.cpp
ReverseIterationTest.cpp
ReplaceFileTest.cpp
ScaledNumberTest.cpp
SourceMgrTest.cpp
SpecialCaseListTest.cpp
StringPool.cpp
SwapByteOrderTest.cpp
TarWriterTest.cpp
TargetParserTest.cpp
ThreadLocalTest.cpp
ThreadPool.cpp
Threading.cpp
TimerTest.cpp
TypeNameTest.cpp
TrailingObjectsTest.cpp
TrigramIndexTest.cpp
UnicodeTest.cpp
YAMLIOTest.cpp
YAMLParserTest.cpp
formatted_raw_ostream_test.cpp
raw_ostream_test.cpp
raw_pwrite_stream_test.cpp
raw_sha1_ostream_test.cpp
xxhashTest.cpp
)
target_link_libraries(SupportTests PRIVATE LLVMTestingSupport)
# Disable all warning for AlignOfTest.cpp,
# as it does things intentionally, and there is no reliable way of
# disabling all warnings for all the compilers by using pragmas.
set_source_files_properties(AlignOfTest.cpp PROPERTIES COMPILE_FLAGS -w)
# ManagedStatic.cpp uses <pthread>.
target_link_libraries(SupportTests PRIVATE LLVMTestingSupport ${LLVM_PTHREAD_LIB})
add_subdirectory(DynamicLibrary)

View File

@ -0,0 +1,97 @@
//===- CachePruningTest.cpp -----------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/CachePruning.h"
#include "llvm/Support/Error.h"
#include "gtest/gtest.h"
using namespace llvm;
TEST(CachePruningPolicyParser, Empty) {
auto P = parseCachePruningPolicy("");
ASSERT_TRUE(bool(P));
EXPECT_EQ(std::chrono::seconds(1200), P->Interval);
EXPECT_EQ(std::chrono::hours(7 * 24), P->Expiration);
EXPECT_EQ(75u, P->MaxSizePercentageOfAvailableSpace);
}
TEST(CachePruningPolicyParser, Interval) {
auto P = parseCachePruningPolicy("prune_interval=1s");
ASSERT_TRUE(bool(P));
EXPECT_EQ(std::chrono::seconds(1), P->Interval);
P = parseCachePruningPolicy("prune_interval=2m");
ASSERT_TRUE(bool(P));
EXPECT_EQ(std::chrono::minutes(2), *P->Interval);
P = parseCachePruningPolicy("prune_interval=3h");
ASSERT_TRUE(bool(P));
EXPECT_EQ(std::chrono::hours(3), *P->Interval);
}
TEST(CachePruningPolicyParser, Expiration) {
auto P = parseCachePruningPolicy("prune_after=1s");
ASSERT_TRUE(bool(P));
EXPECT_EQ(std::chrono::seconds(1), P->Expiration);
}
TEST(CachePruningPolicyParser, MaxSizePercentageOfAvailableSpace) {
auto P = parseCachePruningPolicy("cache_size=100%");
ASSERT_TRUE(bool(P));
EXPECT_EQ(100u, P->MaxSizePercentageOfAvailableSpace);
EXPECT_EQ(0u, P->MaxSizeBytes);
}
TEST(CachePruningPolicyParser, MaxSizeBytes) {
auto P = parseCachePruningPolicy("cache_size_bytes=1");
ASSERT_TRUE(bool(P));
EXPECT_EQ(75u, P->MaxSizePercentageOfAvailableSpace);
EXPECT_EQ(1u, P->MaxSizeBytes);
P = parseCachePruningPolicy("cache_size_bytes=2k");
ASSERT_TRUE(bool(P));
EXPECT_EQ(75u, P->MaxSizePercentageOfAvailableSpace);
EXPECT_EQ(2u * 1024u, P->MaxSizeBytes);
P = parseCachePruningPolicy("cache_size_bytes=3m");
ASSERT_TRUE(bool(P));
EXPECT_EQ(75u, P->MaxSizePercentageOfAvailableSpace);
EXPECT_EQ(3u * 1024u * 1024u, P->MaxSizeBytes);
P = parseCachePruningPolicy("cache_size_bytes=4G");
ASSERT_TRUE(bool(P));
EXPECT_EQ(75u, P->MaxSizePercentageOfAvailableSpace);
EXPECT_EQ(4ull * 1024ull * 1024ull * 1024ull, P->MaxSizeBytes);
}
TEST(CachePruningPolicyParser, Multiple) {
auto P = parseCachePruningPolicy("prune_after=1s:cache_size=50%");
ASSERT_TRUE(bool(P));
EXPECT_EQ(std::chrono::seconds(1200), P->Interval);
EXPECT_EQ(std::chrono::seconds(1), P->Expiration);
EXPECT_EQ(50u, P->MaxSizePercentageOfAvailableSpace);
}
TEST(CachePruningPolicyParser, Errors) {
EXPECT_EQ("Duration must not be empty",
toString(parseCachePruningPolicy("prune_interval=").takeError()));
EXPECT_EQ("'foo' not an integer",
toString(parseCachePruningPolicy("prune_interval=foos").takeError()));
EXPECT_EQ("'24x' must end with one of 's', 'm' or 'h'",
toString(parseCachePruningPolicy("prune_interval=24x").takeError()));
EXPECT_EQ("'foo' must be a percentage",
toString(parseCachePruningPolicy("cache_size=foo").takeError()));
EXPECT_EQ("'foo' not an integer",
toString(parseCachePruningPolicy("cache_size=foo%").takeError()));
EXPECT_EQ("'101' must be between 0 and 100",
toString(parseCachePruningPolicy("cache_size=101%").takeError()));
EXPECT_EQ(
"'foo' not an integer",
toString(parseCachePruningPolicy("cache_size_bytes=foo").takeError()));
EXPECT_EQ(
"'foo' not an integer",
toString(parseCachePruningPolicy("cache_size_bytes=foom").takeError()));
EXPECT_EQ("Unknown key: 'foo'",
toString(parseCachePruningPolicy("foo=bar").takeError()));
}

View File

@ -0,0 +1,405 @@
//===---------- llvm/unittest/Support/Casting.cpp - Casting tests ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/Casting.h"
#include "llvm/IR/User.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
#include <cstdlib>
namespace llvm {
// Used to test illegal cast. If a cast doesn't match any of the "real" ones,
// it will match this one.
struct IllegalCast;
template <typename T> IllegalCast *cast(...) { return nullptr; }
// set up two example classes
// with conversion facility
//
struct bar {
bar() {}
struct foo *baz();
struct foo *caz();
struct foo *daz();
struct foo *naz();
private:
bar(const bar &);
};
struct foo {
void ext() const;
/* static bool classof(const bar *X) {
cerr << "Classof: " << X << "\n";
return true;
}*/
};
struct base {
virtual ~base() {}
};
struct derived : public base {
static bool classof(const base *B) { return true; }
};
template <> struct isa_impl<foo, bar> {
static inline bool doit(const bar &Val) {
dbgs() << "Classof: " << &Val << "\n";
return true;
}
};
template <typename T> struct isa_impl<foo, T> {
static inline bool doit(const T &Val) { return false; }
};
foo *bar::baz() {
return cast<foo>(this);
}
foo *bar::caz() {
return cast_or_null<foo>(this);
}
foo *bar::daz() {
return dyn_cast<foo>(this);
}
foo *bar::naz() {
return dyn_cast_or_null<foo>(this);
}
bar *fub();
template <> struct simplify_type<foo> {
typedef int SimpleType;
static SimpleType getSimplifiedValue(foo &Val) { return 0; }
};
} // End llvm namespace
using namespace llvm;
// Test the peculiar behavior of Use in simplify_type.
static_assert(std::is_same<simplify_type<Use>::SimpleType, Value *>::value,
"Use doesn't simplify correctly!");
static_assert(std::is_same<simplify_type<Use *>::SimpleType, Value *>::value,
"Use doesn't simplify correctly!");
// Test that a regular class behaves as expected.
static_assert(std::is_same<simplify_type<foo>::SimpleType, int>::value,
"Unexpected simplify_type result!");
static_assert(std::is_same<simplify_type<foo *>::SimpleType, foo *>::value,
"Unexpected simplify_type result!");
namespace {
const foo *null_foo = nullptr;
bar B;
extern bar &B1;
bar &B1 = B;
extern const bar *B2;
// test various configurations of const
const bar &B3 = B1;
const bar *const B4 = B2;
TEST(CastingTest, isa) {
EXPECT_TRUE(isa<foo>(B1));
EXPECT_TRUE(isa<foo>(B2));
EXPECT_TRUE(isa<foo>(B3));
EXPECT_TRUE(isa<foo>(B4));
}
TEST(CastingTest, cast) {
foo &F1 = cast<foo>(B1);
EXPECT_NE(&F1, null_foo);
const foo *F3 = cast<foo>(B2);
EXPECT_NE(F3, null_foo);
const foo *F4 = cast<foo>(B2);
EXPECT_NE(F4, null_foo);
const foo &F5 = cast<foo>(B3);
EXPECT_NE(&F5, null_foo);
const foo *F6 = cast<foo>(B4);
EXPECT_NE(F6, null_foo);
// Can't pass null pointer to cast<>.
// foo *F7 = cast<foo>(fub());
// EXPECT_EQ(F7, null_foo);
foo *F8 = B1.baz();
EXPECT_NE(F8, null_foo);
std::unique_ptr<const bar> BP(B2);
auto FP = cast<foo>(std::move(BP));
static_assert(std::is_same<std::unique_ptr<const foo>, decltype(FP)>::value,
"Incorrect deduced return type!");
EXPECT_NE(FP.get(), null_foo);
FP.release();
}
TEST(CastingTest, cast_or_null) {
const foo *F11 = cast_or_null<foo>(B2);
EXPECT_NE(F11, null_foo);
const foo *F12 = cast_or_null<foo>(B2);
EXPECT_NE(F12, null_foo);
const foo *F13 = cast_or_null<foo>(B4);
EXPECT_NE(F13, null_foo);
const foo *F14 = cast_or_null<foo>(fub()); // Shouldn't print.
EXPECT_EQ(F14, null_foo);
foo *F15 = B1.caz();
EXPECT_NE(F15, null_foo);
std::unique_ptr<const bar> BP(fub());
auto FP = cast_or_null<foo>(std::move(BP));
EXPECT_EQ(FP.get(), null_foo);
}
TEST(CastingTest, dyn_cast) {
const foo *F1 = dyn_cast<foo>(B2);
EXPECT_NE(F1, null_foo);
const foo *F2 = dyn_cast<foo>(B2);
EXPECT_NE(F2, null_foo);
const foo *F3 = dyn_cast<foo>(B4);
EXPECT_NE(F3, null_foo);
// Can't pass null pointer to dyn_cast<>.
// foo *F4 = dyn_cast<foo>(fub());
// EXPECT_EQ(F4, null_foo);
foo *F5 = B1.daz();
EXPECT_NE(F5, null_foo);
}
TEST(CastingTest, dyn_cast_or_null) {
const foo *F1 = dyn_cast_or_null<foo>(B2);
EXPECT_NE(F1, null_foo);
const foo *F2 = dyn_cast_or_null<foo>(B2);
EXPECT_NE(F2, null_foo);
const foo *F3 = dyn_cast_or_null<foo>(B4);
EXPECT_NE(F3, null_foo);
foo *F4 = dyn_cast_or_null<foo>(fub());
EXPECT_EQ(F4, null_foo);
foo *F5 = B1.naz();
EXPECT_NE(F5, null_foo);
}
std::unique_ptr<derived> newd() { return llvm::make_unique<derived>(); }
std::unique_ptr<base> newb() { return llvm::make_unique<derived>(); }
TEST(CastingTest, unique_dyn_cast) {
derived *OrigD = nullptr;
auto D = llvm::make_unique<derived>();
OrigD = D.get();
// Converting from D to itself is valid, it should return a new unique_ptr
// and the old one should become nullptr.
auto NewD = unique_dyn_cast<derived>(D);
ASSERT_EQ(OrigD, NewD.get());
ASSERT_EQ(nullptr, D);
// Converting from D to B is valid, B should have a value and D should be
// nullptr.
auto B = unique_dyn_cast<base>(NewD);
ASSERT_EQ(OrigD, B.get());
ASSERT_EQ(nullptr, NewD);
// Converting from B to itself is valid, it should return a new unique_ptr
// and the old one should become nullptr.
auto NewB = unique_dyn_cast<base>(B);
ASSERT_EQ(OrigD, NewB.get());
ASSERT_EQ(nullptr, B);
// Converting from B to D is valid, D should have a value and B should be
// nullptr;
D = unique_dyn_cast<derived>(NewB);
ASSERT_EQ(OrigD, D.get());
ASSERT_EQ(nullptr, NewB);
// Converting between unrelated types should fail. The original value should
// remain unchanged and it should return nullptr.
auto F = unique_dyn_cast<foo>(D);
ASSERT_EQ(nullptr, F);
ASSERT_EQ(OrigD, D.get());
// All of the above should also hold for temporaries.
auto D2 = unique_dyn_cast<derived>(newd());
EXPECT_NE(nullptr, D2);
auto B2 = unique_dyn_cast<derived>(newb());
EXPECT_NE(nullptr, B2);
auto B3 = unique_dyn_cast<base>(newb());
EXPECT_NE(nullptr, B3);
auto F2 = unique_dyn_cast<foo>(newb());
EXPECT_EQ(nullptr, F2);
}
// These lines are errors...
//foo *F20 = cast<foo>(B2); // Yields const foo*
//foo &F21 = cast<foo>(B3); // Yields const foo&
//foo *F22 = cast<foo>(B4); // Yields const foo*
//foo &F23 = cast_or_null<foo>(B1);
//const foo &F24 = cast_or_null<foo>(B3);
const bar *B2 = &B;
} // anonymous namespace
bar *llvm::fub() { return nullptr; }
namespace {
namespace inferred_upcasting {
// This test case verifies correct behavior of inferred upcasts when the
// types are statically known to be OK to upcast. This is the case when,
// for example, Derived inherits from Base, and we do `isa<Base>(Derived)`.
// Note: This test will actually fail to compile without inferred
// upcasting.
class Base {
public:
// No classof. We are testing that the upcast is inferred.
Base() {}
};
class Derived : public Base {
public:
Derived() {}
};
// Even with no explicit classof() in Base, we should still be able to cast
// Derived to its base class.
TEST(CastingTest, UpcastIsInferred) {
Derived D;
EXPECT_TRUE(isa<Base>(D));
Base *BP = dyn_cast<Base>(&D);
EXPECT_TRUE(BP != nullptr);
}
// This test verifies that the inferred upcast takes precedence over an
// explicitly written one. This is important because it verifies that the
// dynamic check gets optimized away.
class UseInferredUpcast {
public:
int Dummy;
static bool classof(const UseInferredUpcast *) {
return false;
}
};
TEST(CastingTest, InferredUpcastTakesPrecedence) {
UseInferredUpcast UIU;
// Since the explicit classof() returns false, this will fail if the
// explicit one is used.
EXPECT_TRUE(isa<UseInferredUpcast>(&UIU));
}
} // end namespace inferred_upcasting
} // end anonymous namespace
// Test that we reject casts of temporaries (and so the illegal cast gets used).
namespace TemporaryCast {
struct pod {};
IllegalCast *testIllegalCast() { return cast<foo>(pod()); }
}
namespace {
namespace pointer_wrappers {
struct Base {
bool IsDerived;
Base(bool IsDerived = false) : IsDerived(IsDerived) {}
};
struct Derived : Base {
Derived() : Base(true) {}
static bool classof(const Base *B) { return B->IsDerived; }
};
class PTy {
Base *B;
public:
PTy(Base *B) : B(B) {}
explicit operator bool() const { return get(); }
Base *get() const { return B; }
};
} // end namespace pointer_wrappers
} // end namespace
namespace llvm {
template <> struct simplify_type<pointer_wrappers::PTy> {
typedef pointer_wrappers::Base *SimpleType;
static SimpleType getSimplifiedValue(pointer_wrappers::PTy &P) {
return P.get();
}
};
template <> struct simplify_type<const pointer_wrappers::PTy> {
typedef pointer_wrappers::Base *SimpleType;
static SimpleType getSimplifiedValue(const pointer_wrappers::PTy &P) {
return P.get();
}
};
} // end namespace llvm
namespace {
namespace pointer_wrappers {
// Some objects.
pointer_wrappers::Base B;
pointer_wrappers::Derived D;
// Mutable "smart" pointers.
pointer_wrappers::PTy MN(nullptr);
pointer_wrappers::PTy MB(&B);
pointer_wrappers::PTy MD(&D);
// Const "smart" pointers.
const pointer_wrappers::PTy CN(nullptr);
const pointer_wrappers::PTy CB(&B);
const pointer_wrappers::PTy CD(&D);
TEST(CastingTest, smart_isa) {
EXPECT_TRUE(!isa<pointer_wrappers::Derived>(MB));
EXPECT_TRUE(!isa<pointer_wrappers::Derived>(CB));
EXPECT_TRUE(isa<pointer_wrappers::Derived>(MD));
EXPECT_TRUE(isa<pointer_wrappers::Derived>(CD));
}
TEST(CastingTest, smart_cast) {
EXPECT_TRUE(cast<pointer_wrappers::Derived>(MD) == &D);
EXPECT_TRUE(cast<pointer_wrappers::Derived>(CD) == &D);
}
TEST(CastingTest, smart_cast_or_null) {
EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(MN) == nullptr);
EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(CN) == nullptr);
EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(MD) == &D);
EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(CD) == &D);
}
TEST(CastingTest, smart_dyn_cast) {
EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(MB) == nullptr);
EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(CB) == nullptr);
EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(MD) == &D);
EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(CD) == &D);
}
TEST(CastingTest, smart_dyn_cast_or_null) {
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MN) == nullptr);
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CN) == nullptr);
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MB) == nullptr);
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CB) == nullptr);
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MD) == &D);
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CD) == &D);
}
} // end namespace pointer_wrappers
} // end namespace

View File

@ -0,0 +1,112 @@
//===- llvm/unittest/Support/Chrono.cpp - Time utilities tests ------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/Chrono.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/FormatVariadic.h"
#include "gtest/gtest.h"
using namespace llvm;
using namespace llvm::sys;
using namespace std::chrono;
namespace {
TEST(Chrono, TimeTConversion) {
EXPECT_EQ(time_t(0), toTimeT(toTimePoint(time_t(0))));
EXPECT_EQ(time_t(1), toTimeT(toTimePoint(time_t(1))));
EXPECT_EQ(time_t(47), toTimeT(toTimePoint(time_t(47))));
TimePoint<> TP;
EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));
TP += seconds(1);
EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));
TP += hours(47);
EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));
}
TEST(Chrono, TimePointFormat) {
using namespace std::chrono;
struct tm TM {};
TM.tm_year = 106;
TM.tm_mon = 0;
TM.tm_mday = 2;
TM.tm_hour = 15;
TM.tm_min = 4;
TM.tm_sec = 5;
TM.tm_isdst = -1;
TimePoint<> T =
system_clock::from_time_t(mktime(&TM)) + nanoseconds(123456789);
// operator<< uses the format YYYY-MM-DD HH:MM:SS.NNNNNNNNN
std::string S;
raw_string_ostream OS(S);
OS << T;
EXPECT_EQ("2006-01-02 15:04:05.123456789", OS.str());
// formatv default style matches operator<<.
EXPECT_EQ("2006-01-02 15:04:05.123456789", formatv("{0}", T).str());
// formatv supports strftime-style format strings.
EXPECT_EQ("15:04:05", formatv("{0:%H:%M:%S}", T).str());
// formatv supports our strftime extensions for sub-second precision.
EXPECT_EQ("123", formatv("{0:%L}", T).str());
EXPECT_EQ("123456", formatv("{0:%f}", T).str());
EXPECT_EQ("123456789", formatv("{0:%N}", T).str());
// our extensions don't interfere with %% escaping.
EXPECT_EQ("%foo", formatv("{0:%%foo}", T).str());
}
// Test that toTimePoint and toTimeT can be called with a arguments with varying
// precisions.
TEST(Chrono, ImplicitConversions) {
std::time_t TimeT = 47;
TimePoint<seconds> Sec = toTimePoint(TimeT);
TimePoint<milliseconds> Milli = toTimePoint(TimeT);
TimePoint<microseconds> Micro = toTimePoint(TimeT);
TimePoint<nanoseconds> Nano = toTimePoint(TimeT);
EXPECT_EQ(Sec, Milli);
EXPECT_EQ(Sec, Micro);
EXPECT_EQ(Sec, Nano);
EXPECT_EQ(TimeT, toTimeT(Sec));
EXPECT_EQ(TimeT, toTimeT(Milli));
EXPECT_EQ(TimeT, toTimeT(Micro));
EXPECT_EQ(TimeT, toTimeT(Nano));
}
TEST(Chrono, DurationFormat) {
EXPECT_EQ("1 h", formatv("{0}", hours(1)).str());
EXPECT_EQ("1 m", formatv("{0}", minutes(1)).str());
EXPECT_EQ("1 s", formatv("{0}", seconds(1)).str());
EXPECT_EQ("1 ms", formatv("{0}", milliseconds(1)).str());
EXPECT_EQ("1 us", formatv("{0}", microseconds(1)).str());
EXPECT_EQ("1 ns", formatv("{0}", nanoseconds(1)).str());
EXPECT_EQ("1 s", formatv("{0:+}", seconds(1)).str());
EXPECT_EQ("1", formatv("{0:-}", seconds(1)).str());
EXPECT_EQ("1000 ms", formatv("{0:ms}", seconds(1)).str());
EXPECT_EQ("1000000 us", formatv("{0:us}", seconds(1)).str());
EXPECT_EQ("1000", formatv("{0:ms-}", seconds(1)).str());
EXPECT_EQ("1,000 ms", formatv("{0:+n}", milliseconds(1000)).str());
EXPECT_EQ("0x3e8", formatv("{0:-x}", milliseconds(1000)).str());
EXPECT_EQ("010", formatv("{0:-3}", milliseconds(10)).str());
EXPECT_EQ("10,000", formatv("{0:ms-n}", seconds(10)).str());
EXPECT_EQ("1.00 s", formatv("{0}", duration<float>(1)).str());
EXPECT_EQ("0.123 s", formatv("{0:+3}", duration<float>(0.123f)).str());
EXPECT_EQ("1.230e-01 s", formatv("{0:+e3}", duration<float>(0.123f)).str());
typedef duration<float, std::ratio<60 * 60 * 24 * 14, 1000000>>
microfortnights;
EXPECT_EQ("1.00", formatv("{0:-}", microfortnights(1)).str());
EXPECT_EQ("1209.60 ms", formatv("{0:ms}", microfortnights(1)).str());
}
} // anonymous namespace

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
//===- llvm/unittest/Support/CompressionTest.cpp - Compression tests ------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements unit tests for the Compression functions.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/Compression.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Error.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace {
#if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ
void TestZlibCompression(StringRef Input, zlib::CompressionLevel Level) {
SmallString<32> Compressed;
SmallString<32> Uncompressed;
Error E = zlib::compress(Input, Compressed, Level);
EXPECT_FALSE(E);
consumeError(std::move(E));
// Check that uncompressed buffer is the same as original.
E = zlib::uncompress(Compressed, Uncompressed, Input.size());
EXPECT_FALSE(E);
consumeError(std::move(E));
EXPECT_EQ(Input, Uncompressed);
if (Input.size() > 0) {
// Uncompression fails if expected length is too short.
E = zlib::uncompress(Compressed, Uncompressed, Input.size() - 1);
EXPECT_EQ("zlib error: Z_BUF_ERROR", llvm::toString(std::move(E)));
}
}
TEST(CompressionTest, Zlib) {
TestZlibCompression("", zlib::DefaultCompression);
TestZlibCompression("hello, world!", zlib::NoCompression);
TestZlibCompression("hello, world!", zlib::BestSizeCompression);
TestZlibCompression("hello, world!", zlib::BestSpeedCompression);
TestZlibCompression("hello, world!", zlib::DefaultCompression);
const size_t kSize = 1024;
char BinaryData[kSize];
for (size_t i = 0; i < kSize; ++i) {
BinaryData[i] = i & 255;
}
StringRef BinaryDataStr(BinaryData, kSize);
TestZlibCompression(BinaryDataStr, zlib::NoCompression);
TestZlibCompression(BinaryDataStr, zlib::BestSizeCompression);
TestZlibCompression(BinaryDataStr, zlib::BestSpeedCompression);
TestZlibCompression(BinaryDataStr, zlib::DefaultCompression);
}
TEST(CompressionTest, ZlibCRC32) {
EXPECT_EQ(
0x414FA339U,
zlib::crc32(StringRef("The quick brown fox jumps over the lazy dog")));
}
#endif
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
//===- llvm/unittest/Support/CrashRecoveryTest.cpp ------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/Compiler.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "gtest/gtest.h"
#ifdef LLVM_ON_WIN32
#define WIN32_LEAN_AND_MEAN
#define NOGDI
#include <windows.h>
#endif
using namespace llvm;
using namespace llvm::sys;
static int GlobalInt = 0;
static void nullDeref() { *(volatile int *)0x10 = 0; }
static void incrementGlobal() { ++GlobalInt; }
static void llvmTrap() { LLVM_BUILTIN_TRAP; }
TEST(CrashRecoveryTest, Basic) {
llvm::CrashRecoveryContext::Enable();
GlobalInt = 0;
EXPECT_TRUE(CrashRecoveryContext().RunSafely(incrementGlobal));
EXPECT_EQ(1, GlobalInt);
EXPECT_FALSE(CrashRecoveryContext().RunSafely(nullDeref));
EXPECT_FALSE(CrashRecoveryContext().RunSafely(llvmTrap));
}
struct IncrementGlobalCleanup : CrashRecoveryContextCleanup {
IncrementGlobalCleanup(CrashRecoveryContext *CRC)
: CrashRecoveryContextCleanup(CRC) {}
virtual void recoverResources() { ++GlobalInt; }
};
static void noop() {}
TEST(CrashRecoveryTest, Cleanup) {
llvm::CrashRecoveryContext::Enable();
GlobalInt = 0;
{
CrashRecoveryContext CRC;
CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));
EXPECT_TRUE(CRC.RunSafely(noop));
} // run cleanups
EXPECT_EQ(1, GlobalInt);
GlobalInt = 0;
{
CrashRecoveryContext CRC;
CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));
EXPECT_FALSE(CRC.RunSafely(nullDeref));
} // run cleanups
EXPECT_EQ(1, GlobalInt);
}
#ifdef LLVM_ON_WIN32
static void raiseIt() {
RaiseException(123, EXCEPTION_NONCONTINUABLE, 0, NULL);
}
TEST(CrashRecoveryTest, RaiseException) {
llvm::CrashRecoveryContext::Enable();
EXPECT_FALSE(CrashRecoveryContext().RunSafely(raiseIt));
}
static void outputString() {
OutputDebugStringA("output for debugger\n");
}
TEST(CrashRecoveryTest, CallOutputDebugString) {
llvm::CrashRecoveryContext::Enable();
EXPECT_TRUE(CrashRecoveryContext().RunSafely(outputString));
}
#endif

View File

@ -0,0 +1,120 @@
//===- llvm/unittest/Support/DataExtractorTest.cpp - DataExtractor tests --===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/DataExtractor.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace {
const char numberData[] = "\x80\x90\xFF\xFF\x80\x00\x00\x00";
const char stringData[] = "hellohello\0hello";
const char leb128data[] = "\xA6\x49";
const char bigleb128data[] = "\xAA\xA9\xFF\xAA\xFF\xAA\xFF\x4A";
TEST(DataExtractorTest, OffsetOverflow) {
DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
EXPECT_FALSE(DE.isValidOffsetForDataOfSize(-2U, 5));
}
TEST(DataExtractorTest, UnsignedNumbers) {
DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
uint32_t offset = 0;
EXPECT_EQ(0x80U, DE.getU8(&offset));
EXPECT_EQ(1U, offset);
offset = 0;
EXPECT_EQ(0x8090U, DE.getU16(&offset));
EXPECT_EQ(2U, offset);
offset = 0;
EXPECT_EQ(0x8090FFFFU, DE.getU32(&offset));
EXPECT_EQ(4U, offset);
offset = 0;
EXPECT_EQ(0x8090FFFF80000000ULL, DE.getU64(&offset));
EXPECT_EQ(8U, offset);
offset = 0;
EXPECT_EQ(0x8090FFFF80000000ULL, DE.getAddress(&offset));
EXPECT_EQ(8U, offset);
offset = 0;
uint32_t data[2];
EXPECT_EQ(data, DE.getU32(&offset, data, 2));
EXPECT_EQ(0x8090FFFFU, data[0]);
EXPECT_EQ(0x80000000U, data[1]);
EXPECT_EQ(8U, offset);
offset = 0;
// Now for little endian.
DE = DataExtractor(StringRef(numberData, sizeof(numberData)-1), true, 4);
EXPECT_EQ(0x9080U, DE.getU16(&offset));
EXPECT_EQ(2U, offset);
offset = 0;
EXPECT_EQ(0xFFFF9080U, DE.getU32(&offset));
EXPECT_EQ(4U, offset);
offset = 0;
EXPECT_EQ(0x80FFFF9080ULL, DE.getU64(&offset));
EXPECT_EQ(8U, offset);
offset = 0;
EXPECT_EQ(0xFFFF9080U, DE.getAddress(&offset));
EXPECT_EQ(4U, offset);
offset = 0;
EXPECT_EQ(data, DE.getU32(&offset, data, 2));
EXPECT_EQ(0xFFFF9080U, data[0]);
EXPECT_EQ(0x80U, data[1]);
EXPECT_EQ(8U, offset);
}
TEST(DataExtractorTest, SignedNumbers) {
DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
uint32_t offset = 0;
EXPECT_EQ(-128, DE.getSigned(&offset, 1));
EXPECT_EQ(1U, offset);
offset = 0;
EXPECT_EQ(-32624, DE.getSigned(&offset, 2));
EXPECT_EQ(2U, offset);
offset = 0;
EXPECT_EQ(-2137980929, DE.getSigned(&offset, 4));
EXPECT_EQ(4U, offset);
offset = 0;
EXPECT_EQ(-9182558167379214336LL, DE.getSigned(&offset, 8));
EXPECT_EQ(8U, offset);
}
TEST(DataExtractorTest, Strings) {
DataExtractor DE(StringRef(stringData, sizeof(stringData)-1), false, 8);
uint32_t offset = 0;
EXPECT_EQ(stringData, DE.getCStr(&offset));
EXPECT_EQ(11U, offset);
EXPECT_EQ(nullptr, DE.getCStr(&offset));
EXPECT_EQ(11U, offset);
}
TEST(DataExtractorTest, LEB128) {
DataExtractor DE(StringRef(leb128data, sizeof(leb128data)-1), false, 8);
uint32_t offset = 0;
EXPECT_EQ(9382ULL, DE.getULEB128(&offset));
EXPECT_EQ(2U, offset);
offset = 0;
EXPECT_EQ(-7002LL, DE.getSLEB128(&offset));
EXPECT_EQ(2U, offset);
DataExtractor BDE(StringRef(bigleb128data, sizeof(bigleb128data)-1), false,8);
offset = 0;
EXPECT_EQ(42218325750568106ULL, BDE.getULEB128(&offset));
EXPECT_EQ(8U, offset);
offset = 0;
EXPECT_EQ(-29839268287359830LL, BDE.getSLEB128(&offset));
EXPECT_EQ(8U, offset);
}
}

View File

@ -0,0 +1,34 @@
//===- llvm/unittest/Support/DebugTest.cpp --------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
#include <string>
using namespace llvm;
#ifndef NDEBUG
TEST(DebugTest, Basic) {
std::string s1, s2;
raw_string_ostream os1(s1), os2(s2);
static const char *DT[] = {"A", "B"};
llvm::DebugFlag = true;
setCurrentDebugTypes(DT, 2);
DEBUG_WITH_TYPE("A", os1 << "A");
DEBUG_WITH_TYPE("B", os1 << "B");
EXPECT_EQ("AB", os1.str());
setCurrentDebugType("A");
DEBUG_WITH_TYPE("A", os2 << "A");
DEBUG_WITH_TYPE("B", os2 << "B");
EXPECT_EQ("A", os2.str());
}
#endif

View File

@ -0,0 +1,35 @@
set(LLVM_LINK_COMPONENTS Support)
add_library(DynamicLibraryLib STATIC ExportedFuncs.cxx)
set_target_properties(DynamicLibraryLib PROPERTIES FOLDER "Tests")
add_llvm_unittest(DynamicLibraryTests DynamicLibraryTest.cpp)
target_link_libraries(DynamicLibraryTests PRIVATE DynamicLibraryLib)
export_executable_symbols(DynamicLibraryTests)
function(dynlib_add_module NAME)
add_library(${NAME} SHARED PipSqueak.cxx)
set_target_properties(${NAME} PROPERTIES FOLDER "Tests")
set_output_directory(${NAME}
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
)
set_target_properties(${NAME}
PROPERTIES PREFIX ""
SUFFIX ".so"
)
add_dependencies(DynamicLibraryTests ${NAME})
endfunction(dynlib_add_module)
# Revert -Wl,-z,nodelete on this test since it relies on the file
# being unloaded.
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
string(REPLACE "-Wl,-z,nodelete" "" CMAKE_SHARED_LINKER_FLAGS
${CMAKE_SHARED_LINKER_FLAGS})
endif()
dynlib_add_module(PipSqueak)
dynlib_add_module(SecondLib)

View File

@ -0,0 +1,176 @@
//===- llvm/unittest/Support/DynamicLibrary/DynamicLibraryTest.cpp --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Config/config.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "gtest/gtest.h"
#include "PipSqueak.h"
using namespace llvm;
using namespace llvm::sys;
std::string LibPath(const std::string Name = "PipSqueak") {
const std::vector<testing::internal::string>& Argvs = testing::internal::GetArgvs();
const char *Argv0 = Argvs.size() > 0 ? Argvs[0].c_str() : "DynamicLibraryTests";
void *Ptr = (void*)(intptr_t)TestA;
std::string Path = fs::getMainExecutable(Argv0, Ptr);
llvm::SmallString<256> Buf(path::parent_path(Path));
path::append(Buf, (Name+".so").c_str());
return Buf.str();
}
#if defined(_WIN32) || (defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN))
typedef void (*SetStrings)(std::string &GStr, std::string &LStr);
typedef void (*TestOrder)(std::vector<std::string> &V);
typedef const char *(*GetString)();
template <class T> static T FuncPtr(void *Ptr) {
union {
T F;
void *P;
} Tmp;
Tmp.P = Ptr;
return Tmp.F;
}
template <class T> static void* PtrFunc(T *Func) {
union {
T *F;
void *P;
} Tmp;
Tmp.F = Func;
return Tmp.P;
}
static const char *OverloadTestA() { return "OverloadCall"; }
std::string StdString(const char *Ptr) { return Ptr ? Ptr : ""; }
TEST(DynamicLibrary, Overload) {
{
std::string Err;
llvm_shutdown_obj Shutdown;
DynamicLibrary DL =
DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err);
EXPECT_TRUE(DL.isValid());
EXPECT_TRUE(Err.empty());
GetString GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA"));
EXPECT_TRUE(GS != nullptr && GS != &TestA);
EXPECT_EQ(StdString(GS()), "LibCall");
GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
EXPECT_TRUE(GS != nullptr && GS != &TestA);
EXPECT_EQ(StdString(GS()), "LibCall");
DL = DynamicLibrary::getPermanentLibrary(nullptr, &Err);
EXPECT_TRUE(DL.isValid());
EXPECT_TRUE(Err.empty());
// Test overloading local symbols does not occur by default
GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
EXPECT_TRUE(GS != nullptr && GS == &TestA);
EXPECT_EQ(StdString(GS()), "ProcessCall");
GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA"));
EXPECT_TRUE(GS != nullptr && GS == &TestA);
EXPECT_EQ(StdString(GS()), "ProcessCall");
// Test overloading by forcing library priority when searching for a symbol
DynamicLibrary::SearchOrder = DynamicLibrary::SO_LoadedFirst;
GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
EXPECT_TRUE(GS != nullptr && GS != &TestA);
EXPECT_EQ(StdString(GS()), "LibCall");
DynamicLibrary::AddSymbol("TestA", PtrFunc(&OverloadTestA));
GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA"));
EXPECT_TRUE(GS != nullptr && GS != &OverloadTestA);
GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
EXPECT_TRUE(GS != nullptr && GS == &OverloadTestA);
EXPECT_EQ(StdString(GS()), "OverloadCall");
}
EXPECT_TRUE(FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol(
"TestA")) == nullptr);
// Check serach ordering is reset to default after call to llvm_shutdown
EXPECT_TRUE(DynamicLibrary::SearchOrder == DynamicLibrary::SO_Linker);
}
TEST(DynamicLibrary, Shutdown) {
std::string A("PipSqueak"), B, C("SecondLib");
std::vector<std::string> Order;
{
std::string Err;
llvm_shutdown_obj Shutdown;
DynamicLibrary DL =
DynamicLibrary::getPermanentLibrary(LibPath(A).c_str(), &Err);
EXPECT_TRUE(DL.isValid());
EXPECT_TRUE(Err.empty());
SetStrings SS_0 = FuncPtr<SetStrings>(
DynamicLibrary::SearchForAddressOfSymbol("SetStrings"));
EXPECT_TRUE(SS_0 != nullptr);
SS_0(A, B);
EXPECT_EQ(B, "Local::Local(PipSqueak)");
TestOrder TO_0 = FuncPtr<TestOrder>(
DynamicLibrary::SearchForAddressOfSymbol("TestOrder"));
EXPECT_TRUE(TO_0 != nullptr);
DynamicLibrary DL2 =
DynamicLibrary::getPermanentLibrary(LibPath(C).c_str(), &Err);
EXPECT_TRUE(DL2.isValid());
EXPECT_TRUE(Err.empty());
// Should find latest version of symbols in SecondLib
SetStrings SS_1 = FuncPtr<SetStrings>(
DynamicLibrary::SearchForAddressOfSymbol("SetStrings"));
EXPECT_TRUE(SS_1 != nullptr);
EXPECT_TRUE(SS_0 != SS_1);
TestOrder TO_1 = FuncPtr<TestOrder>(
DynamicLibrary::SearchForAddressOfSymbol("TestOrder"));
EXPECT_TRUE(TO_1 != nullptr);
EXPECT_TRUE(TO_0 != TO_1);
B.clear();
SS_1(C, B);
EXPECT_EQ(B, "Local::Local(SecondLib)");
TO_0(Order);
TO_1(Order);
}
EXPECT_EQ(A, "Global::~Global");
EXPECT_EQ(B, "Local::~Local");
EXPECT_TRUE(FuncPtr<SetStrings>(DynamicLibrary::SearchForAddressOfSymbol(
"SetStrings")) == nullptr);
// Test unload/destruction ordering
EXPECT_EQ(Order.size(), 2UL);
EXPECT_EQ(Order.front(), "SecondLib");
EXPECT_EQ(Order.back(), "PipSqueak");
}
#else
TEST(DynamicLibrary, Unsupported) {
std::string Err;
DynamicLibrary DL =
DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err);
EXPECT_FALSE(DL.isValid());
EXPECT_EQ(Err, "dlopen() not supported on this platform");
}
#endif

View File

@ -0,0 +1,16 @@
//===- llvm/unittest/Support/DynamicLibrary/DynamicLibraryLib.cpp ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "PipSqueak.h"
#ifndef PIPSQUEAK_TESTA_RETURN
#define PIPSQUEAK_TESTA_RETURN "ProcessCall"
#endif
extern "C" PIPSQUEAK_EXPORT const char *TestA() { return PIPSQUEAK_TESTA_RETURN; }

Some files were not shown because too many files have changed in this diff Show More