summaryrefslogtreecommitdiff
path: root/unittests/Support
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /unittests/Support
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'unittests/Support')
-rw-r--r--unittests/Support/ARMAttributeParser.cpp1
-rw-r--r--unittests/Support/BinaryStreamTest.cpp97
-rw-r--r--unittests/Support/CMakeLists.txt5
-rw-r--r--unittests/Support/Chrono.cpp52
-rw-r--r--unittests/Support/CommandLineTest.cpp35
-rw-r--r--unittests/Support/ConvertUTFTest.cpp2
-rw-r--r--unittests/Support/DynamicLibrary/CMakeLists.txt11
-rw-r--r--unittests/Support/ErrorTest.cpp116
-rw-r--r--unittests/Support/FileOutputBufferTest.cpp28
-rw-r--r--unittests/Support/FormatVariadicTest.cpp31
-rw-r--r--unittests/Support/GlobPatternTest.cpp9
-rw-r--r--unittests/Support/Host.cpp45
-rw-r--r--unittests/Support/LEB128Test.cpp33
-rw-r--r--unittests/Support/ManagedStatic.cpp1
-rw-r--r--unittests/Support/MemoryTest.cpp20
-rw-r--r--unittests/Support/Path.cpp130
-rw-r--r--unittests/Support/ProcessTest.cpp10
-rw-r--r--unittests/Support/ProgramTest.cpp23
-rw-r--r--unittests/Support/RegexTest.cpp8
-rw-r--r--unittests/Support/ReplaceFileTest.cpp88
-rw-r--r--unittests/Support/ReverseIterationTest.cpp110
-rw-r--r--unittests/Support/SourceMgrTest.cpp10
-rw-r--r--unittests/Support/SpecialCaseListTest.cpp165
-rw-r--r--unittests/Support/TarWriterTest.cpp129
-rw-r--r--unittests/Support/TargetParserTest.cpp405
-rw-r--r--unittests/Support/YAMLIOTest.cpp94
-rw-r--r--unittests/Support/YAMLParserTest.cpp1
27 files changed, 1225 insertions, 434 deletions
diff --git a/unittests/Support/ARMAttributeParser.cpp b/unittests/Support/ARMAttributeParser.cpp
index 1df03db6d07f..994011872b96 100644
--- a/unittests/Support/ARMAttributeParser.cpp
+++ b/unittests/Support/ARMAttributeParser.cpp
@@ -1,6 +1,5 @@
#include "llvm/Support/ARMAttributeParser.h"
#include "llvm/Support/ARMBuildAttributes.h"
-#include "llvm/Support/LEB128.h"
#include "gtest/gtest.h"
#include <string>
diff --git a/unittests/Support/BinaryStreamTest.cpp b/unittests/Support/BinaryStreamTest.cpp
index e257583e4b12..35a010e73c7b 100644
--- a/unittests/Support/BinaryStreamTest.cpp
+++ b/unittests/Support/BinaryStreamTest.cpp
@@ -17,8 +17,6 @@
#include "gtest/gtest.h"
-#include <unordered_map>
-#include <utility>
using namespace llvm;
using namespace llvm::support;
@@ -36,7 +34,7 @@ public:
Error readBytes(uint32_t Offset, uint32_t Size,
ArrayRef<uint8_t> &Buffer) override {
- if (auto EC = checkOffset(Offset, Size))
+ if (auto EC = checkOffsetForRead(Offset, Size))
return EC;
uint32_t S = startIndex(Offset);
auto Ref = Data.drop_front(S);
@@ -55,7 +53,7 @@ public:
Error readLongestContiguousChunk(uint32_t Offset,
ArrayRef<uint8_t> &Buffer) override {
- if (auto EC = checkOffset(Offset, 1))
+ if (auto EC = checkOffsetForRead(Offset, 1))
return EC;
uint32_t S = startIndex(Offset);
Buffer = Data.drop_front(S);
@@ -65,7 +63,7 @@ public:
uint32_t getLength() override { return Data.size(); }
Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> SrcData) override {
- if (auto EC = checkOffset(Offset, SrcData.size()))
+ if (auto EC = checkOffsetForWrite(Offset, SrcData.size()))
return EC;
if (SrcData.empty())
return Error::success();
@@ -267,6 +265,56 @@ TEST_F(BinaryStreamTest, StreamRefBounds) {
}
}
+TEST_F(BinaryStreamTest, StreamRefDynamicSize) {
+ StringRef Strings[] = {"1", "2", "3", "4"};
+ AppendingBinaryByteStream Stream(support::little);
+
+ BinaryStreamWriter Writer(Stream);
+ BinaryStreamReader Reader(Stream);
+ const uint8_t *Byte;
+ StringRef Str;
+
+ // When the stream is empty, it should report a 0 length and we should get an
+ // error trying to read even 1 byte from it.
+ BinaryStreamRef ConstRef(Stream);
+ EXPECT_EQ(0U, ConstRef.getLength());
+ EXPECT_THAT_ERROR(Reader.readObject(Byte), Failed());
+
+ // But if we write to it, its size should increase and we should be able to
+ // read not just a byte, but the string that was written.
+ EXPECT_THAT_ERROR(Writer.writeCString(Strings[0]), Succeeded());
+ EXPECT_EQ(2U, ConstRef.getLength());
+ EXPECT_THAT_ERROR(Reader.readObject(Byte), Succeeded());
+
+ Reader.setOffset(0);
+ EXPECT_THAT_ERROR(Reader.readCString(Str), Succeeded());
+ EXPECT_EQ(Str, Strings[0]);
+
+ // If we drop some bytes from the front, we should still track the length as
+ // the
+ // underlying stream grows.
+ BinaryStreamRef Dropped = ConstRef.drop_front(1);
+ EXPECT_EQ(1U, Dropped.getLength());
+
+ EXPECT_THAT_ERROR(Writer.writeCString(Strings[1]), Succeeded());
+ EXPECT_EQ(4U, ConstRef.getLength());
+ EXPECT_EQ(3U, Dropped.getLength());
+
+ // If we drop zero bytes from the back, we should continue tracking the
+ // length.
+ Dropped = Dropped.drop_back(0);
+ EXPECT_THAT_ERROR(Writer.writeCString(Strings[2]), Succeeded());
+ EXPECT_EQ(6U, ConstRef.getLength());
+ EXPECT_EQ(5U, Dropped.getLength());
+
+ // If we drop non-zero bytes from the back, we should stop tracking the
+ // length.
+ Dropped = Dropped.drop_back(1);
+ EXPECT_THAT_ERROR(Writer.writeCString(Strings[3]), Succeeded());
+ EXPECT_EQ(8U, ConstRef.getLength());
+ EXPECT_EQ(4U, Dropped.getLength());
+}
+
TEST_F(BinaryStreamTest, DropOperations) {
std::vector<uint8_t> InputData = {1, 2, 3, 4, 5, 4, 3, 2, 1};
auto RefData = makeArrayRef(InputData);
@@ -314,7 +362,6 @@ TEST_F(BinaryStreamTest, MutableBinaryByteStreamBounds) {
// For every combination of input stream and output stream.
for (auto &Stream : Streams) {
- MutableArrayRef<uint8_t> Buffer;
ASSERT_EQ(InputData.size(), Stream.Input->getLength());
// 1. Try two reads that are supposed to work. One from offset 0, and one
@@ -346,6 +393,25 @@ TEST_F(BinaryStreamTest, MutableBinaryByteStreamBounds) {
}
}
+TEST_F(BinaryStreamTest, AppendingStream) {
+ AppendingBinaryByteStream Stream(llvm::support::little);
+ EXPECT_EQ(0U, Stream.getLength());
+
+ std::vector<uint8_t> InputData = {'T', 'e', 's', 't', 'T', 'e', 's', 't'};
+ auto Test = makeArrayRef(InputData).take_front(4);
+ // Writing past the end of the stream is an error.
+ EXPECT_THAT_ERROR(Stream.writeBytes(4, Test), Failed());
+
+ // Writing exactly at the end of the stream is ok.
+ EXPECT_THAT_ERROR(Stream.writeBytes(0, Test), Succeeded());
+ EXPECT_EQ(Test, Stream.data());
+
+ // And now that the end of the stream is where we couldn't write before, now
+ // we can write.
+ EXPECT_THAT_ERROR(Stream.writeBytes(4, Test), Succeeded());
+ EXPECT_EQ(MutableArrayRef<uint8_t>(InputData), Stream.data());
+}
+
// Test that FixedStreamArray works correctly.
TEST_F(BinaryStreamTest, FixedStreamArray) {
std::vector<uint32_t> Ints = {90823, 12908, 109823, 209823};
@@ -355,7 +421,6 @@ TEST_F(BinaryStreamTest, FixedStreamArray) {
initializeInput(IntBytes, alignof(uint32_t));
for (auto &Stream : Streams) {
- MutableArrayRef<uint8_t> Buffer;
ASSERT_EQ(InputData.size(), Stream.Input->getLength());
FixedStreamArray<uint32_t> Array(*Stream.Input);
@@ -535,7 +600,6 @@ TEST_F(BinaryStreamTest, StreamReaderEnum) {
BinaryStreamReader Reader(*Stream.Input);
- ArrayRef<MyEnum> Array;
FixedStreamArray<MyEnum> FSA;
for (size_t I = 0; I < Enums.size(); ++I) {
@@ -696,6 +760,23 @@ TEST_F(BinaryStreamTest, StringWriterStrings) {
EXPECT_EQ(makeArrayRef(Strings), makeArrayRef(InStrings));
}
}
+
+TEST_F(BinaryStreamTest, StreamWriterAppend) {
+ StringRef Strings[] = {"First", "Second", "Third", "Fourth"};
+ AppendingBinaryByteStream Stream(support::little);
+ BinaryStreamWriter Writer(Stream);
+
+ for (auto &Str : Strings) {
+ EXPECT_THAT_ERROR(Writer.writeCString(Str), Succeeded());
+ }
+
+ BinaryStreamReader Reader(Stream);
+ for (auto &Str : Strings) {
+ StringRef S;
+ EXPECT_THAT_ERROR(Reader.readCString(S), Succeeded());
+ EXPECT_EQ(Str, S);
+ }
+}
}
namespace {
diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt
index 641163e39ed3..299106e0dbf7 100644
--- a/unittests/Support/CMakeLists.txt
+++ b/unittests/Support/CMakeLists.txt
@@ -42,6 +42,7 @@ add_llvm_unittest(SupportTests
ProcessTest.cpp
ProgramTest.cpp
RegexTest.cpp
+ ReverseIterationTest.cpp
ReplaceFileTest.cpp
ScaledNumberTest.cpp
SourceMgrTest.cpp
@@ -67,12 +68,14 @@ add_llvm_unittest(SupportTests
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 LLVMTestingSupport ${LLVM_PTHREAD_LIB})
+target_link_libraries(SupportTests PRIVATE LLVMTestingSupport ${LLVM_PTHREAD_LIB})
add_subdirectory(DynamicLibrary)
diff --git a/unittests/Support/Chrono.cpp b/unittests/Support/Chrono.cpp
index 1410baf848bb..a6b76c81a9c0 100644
--- a/unittests/Support/Chrono.cpp
+++ b/unittests/Support/Chrono.cpp
@@ -31,33 +31,35 @@ TEST(Chrono, TimeTConversion) {
EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));
}
-TEST(Chrono, StringConversion) {
+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 << system_clock::now();
-
- // Do a basic sanity check on the output.
- // The format we expect is YYYY-MM-DD HH:MM:SS.MMMUUUNNN
- StringRef Date, Time;
- std::tie(Date, Time) = StringRef(OS.str()).split(' ');
-
- SmallVector<StringRef, 3> Components;
- Date.split(Components, '-');
- ASSERT_EQ(3u, Components.size());
- EXPECT_EQ(4u, Components[0].size());
- EXPECT_EQ(2u, Components[1].size());
- EXPECT_EQ(2u, Components[2].size());
-
- StringRef Sec, Nano;
- std::tie(Sec, Nano) = Time.split('.');
-
- Components.clear();
- Sec.split(Components, ':');
- ASSERT_EQ(3u, Components.size());
- EXPECT_EQ(2u, Components[0].size());
- EXPECT_EQ(2u, Components[1].size());
- EXPECT_EQ(2u, Components[2].size());
- EXPECT_EQ(9u, Nano.size());
+ 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
diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp
index 660df11446ac..1fb0213b4d18 100644
--- a/unittests/Support/CommandLineTest.cpp
+++ b/unittests/Support/CommandLineTest.cpp
@@ -613,4 +613,39 @@ TEST(CommandLineTest, ResponseFiles) {
llvm::sys::fs::remove(TestDir);
}
+TEST(CommandLineTest, SetDefautValue) {
+ cl::ResetCommandLineParser();
+
+ StackOption<std::string> Opt1("opt1", cl::init("true"));
+ StackOption<bool> Opt2("opt2", cl::init(true));
+ cl::alias Alias("alias", llvm::cl::aliasopt(Opt2));
+ StackOption<int> Opt3("opt3", cl::init(3));
+
+ const char *args[] = {"prog", "-opt1=false", "-opt2", "-opt3"};
+
+ EXPECT_TRUE(
+ cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls()));
+
+ EXPECT_TRUE(Opt1 == "false");
+ EXPECT_TRUE(Opt2);
+ EXPECT_TRUE(Opt3 == 3);
+
+ Opt2 = false;
+ Opt3 = 1;
+
+ cl::ResetAllOptionOccurrences();
+
+ for (auto &OM : cl::getRegisteredOptions(*cl::TopLevelSubCommand)) {
+ cl::Option *O = OM.second;
+ if (O->ArgStr == "opt2") {
+ continue;
+ }
+ O->setDefault();
+ }
+
+ EXPECT_TRUE(Opt1 == "true");
+ EXPECT_TRUE(Opt2);
+ EXPECT_TRUE(Opt3 == 3);
+}
+
} // anonymous namespace
diff --git a/unittests/Support/ConvertUTFTest.cpp b/unittests/Support/ConvertUTFTest.cpp
index 0af09e98a217..dd6e0df3688f 100644
--- a/unittests/Support/ConvertUTFTest.cpp
+++ b/unittests/Support/ConvertUTFTest.cpp
@@ -9,10 +9,8 @@
#include "llvm/Support/ConvertUTF.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Support/Format.h"
#include "gtest/gtest.h"
#include <string>
-#include <utility>
#include <vector>
using namespace llvm;
diff --git a/unittests/Support/DynamicLibrary/CMakeLists.txt b/unittests/Support/DynamicLibrary/CMakeLists.txt
index b5844381362e..4f060e4020d1 100644
--- a/unittests/Support/DynamicLibrary/CMakeLists.txt
+++ b/unittests/Support/DynamicLibrary/CMakeLists.txt
@@ -1,13 +1,15 @@
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 DynamicLibraryLib)
+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}
@@ -22,5 +24,12 @@ function(dynlib_add_module NAME)
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)
diff --git a/unittests/Support/ErrorTest.cpp b/unittests/Support/ErrorTest.cpp
index a762cf023f9c..2629e640f79c 100644
--- a/unittests/Support/ErrorTest.cpp
+++ b/unittests/Support/ErrorTest.cpp
@@ -12,6 +12,8 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
#include <memory>
@@ -386,7 +388,8 @@ TEST(Error, FailureToHandle) {
});
};
- EXPECT_DEATH(FailToHandle(), "Program aborted due to an unhandled Error:")
+ EXPECT_DEATH(FailToHandle(),
+ "Failure value returned from cantFail wrapped call")
<< "Unhandled Error in handleAllErrors call did not cause an "
"abort()";
}
@@ -405,7 +408,7 @@ TEST(Error, FailureFromHandler) {
};
EXPECT_DEATH(ReturnErrorFromHandler(),
- "Program aborted due to an unhandled Error:")
+ "Failure value returned from cantFail wrapped call")
<< " Error returned from handler in handleAllErrors call did not "
"cause abort()";
}
@@ -482,11 +485,12 @@ TEST(Error, CantFailSuccess) {
}
// Test that cantFail results in a crash if you pass it a failure value.
-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS && !defined(NDEBUG)
TEST(Error, CantFailDeath) {
EXPECT_DEATH(
- cantFail(make_error<StringError>("foo", inconvertibleErrorCode())),
- "Failure value returned from cantFail wrapped call")
+ cantFail(make_error<StringError>("foo", inconvertibleErrorCode()),
+ "Cantfail call failed"),
+ "Cantfail call failed")
<< "cantFail(Error) did not cause an abort for failure value";
EXPECT_DEATH(
@@ -604,6 +608,59 @@ TEST(Error, ExpectedCovariance) {
(void)!!A2;
}
+// Test that handleExpected just returns success values.
+TEST(Error, HandleExpectedSuccess) {
+ auto ValOrErr =
+ handleExpected(Expected<int>(42),
+ []() { return Expected<int>(43); });
+ EXPECT_TRUE(!!ValOrErr)
+ << "handleExpected should have returned a success value here";
+ EXPECT_EQ(*ValOrErr, 42)
+ << "handleExpected should have returned the original success value here";
+}
+
+enum FooStrategy { Aggressive, Conservative };
+
+static Expected<int> foo(FooStrategy S) {
+ if (S == Aggressive)
+ return make_error<CustomError>(7);
+ return 42;
+}
+
+// Test that handleExpected invokes the error path if errors are not handled.
+TEST(Error, HandleExpectedUnhandledError) {
+ // foo(Aggressive) should return a CustomError which should pass through as
+ // there is no handler for CustomError.
+ auto ValOrErr =
+ handleExpected(
+ foo(Aggressive),
+ []() { return foo(Conservative); });
+
+ EXPECT_FALSE(!!ValOrErr)
+ << "handleExpected should have returned an error here";
+ auto Err = ValOrErr.takeError();
+ EXPECT_TRUE(Err.isA<CustomError>())
+ << "handleExpected should have returned the CustomError generated by "
+ "foo(Aggressive) here";
+ consumeError(std::move(Err));
+}
+
+// Test that handleExpected invokes the fallback path if errors are handled.
+TEST(Error, HandleExpectedHandledError) {
+ // foo(Aggressive) should return a CustomError which should handle triggering
+ // the fallback path.
+ auto ValOrErr =
+ handleExpected(
+ foo(Aggressive),
+ []() { return foo(Conservative); },
+ [](const CustomError&) { /* do nothing */ });
+
+ EXPECT_TRUE(!!ValOrErr)
+ << "handleExpected should have returned a success value here";
+ EXPECT_EQ(*ValOrErr, 42)
+ << "handleExpected returned the wrong success value";
+}
+
TEST(Error, ErrorCodeConversions) {
// Round-trip a success value to check that it converts correctly.
EXPECT_EQ(errorToErrorCode(errorCodeToError(std::error_code())),
@@ -659,4 +716,53 @@ TEST(Error, ErrorMessage) {
0);
}
+TEST(Error, ErrorMatchers) {
+ EXPECT_THAT_ERROR(Error::success(), Succeeded());
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_THAT_ERROR(make_error<CustomError>(0), Succeeded()),
+ "Expected: succeeded\n Actual: failed (CustomError { 0})");
+
+ EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed());
+ EXPECT_NONFATAL_FAILURE(EXPECT_THAT_ERROR(Error::success(), Failed()),
+ "Expected: failed\n Actual: succeeded");
+
+ EXPECT_THAT_EXPECTED(Expected<int>(0), Succeeded());
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),
+ Succeeded()),
+ "Expected: succeeded\n Actual: failed (CustomError { 0})");
+
+ EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), Failed());
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_THAT_EXPECTED(Expected<int>(0), Failed()),
+ "Expected: failed\n Actual: succeeded with value 0");
+
+ EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(0));
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),
+ HasValue(0)),
+ "Expected: succeeded with value (is equal to 0)\n"
+ " Actual: failed (CustomError { 0})");
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(0)),
+ "Expected: succeeded with value (is equal to 0)\n"
+ " Actual: succeeded with value 1, (isn't equal to 0)");
+
+ EXPECT_THAT_EXPECTED(Expected<int &>(make_error<CustomError>(0)), Failed());
+ int a = 1;
+ EXPECT_THAT_EXPECTED(Expected<int &>(a), Succeeded());
+ EXPECT_THAT_EXPECTED(Expected<int &>(a), HasValue(testing::Eq(1)));
+
+ EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(testing::Gt(0)));
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(testing::Gt(1))),
+ "Expected: succeeded with value (is > 1)\n"
+ " Actual: succeeded with value 0, (isn't > 1)");
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),
+ HasValue(testing::Gt(1))),
+ "Expected: succeeded with value (is > 1)\n"
+ " Actual: failed (CustomError { 0})");
+}
+
} // end anon namespace
diff --git a/unittests/Support/FileOutputBufferTest.cpp b/unittests/Support/FileOutputBufferTest.cpp
index 5f20634d66c2..e7f1fd765bde 100644
--- a/unittests/Support/FileOutputBufferTest.cpp
+++ b/unittests/Support/FileOutputBufferTest.cpp
@@ -40,18 +40,18 @@ TEST(FileOutputBuffer, Test) {
// TEST 1: Verify commit case.
SmallString<128> File1(TestDirectory);
- File1.append("/file1");
+ File1.append("/file1");
{
- ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+ Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
FileOutputBuffer::create(File1, 8192);
- ASSERT_NO_ERROR(BufferOrErr.getError());
+ ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
// Start buffer with special header.
memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
// Write to end of buffer to verify it is writable.
memcpy(Buffer->getBufferEnd() - 20, "AABBCCDDEEFFGGHHIIJJ", 20);
// Commit buffer.
- ASSERT_NO_ERROR(Buffer->commit());
+ ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
}
// Verify file is correct size.
@@ -64,9 +64,9 @@ TEST(FileOutputBuffer, Test) {
SmallString<128> File2(TestDirectory);
File2.append("/file2");
{
- ErrorOr<std::unique_ptr<FileOutputBuffer>> Buffer2OrErr =
+ Expected<std::unique_ptr<FileOutputBuffer>> Buffer2OrErr =
FileOutputBuffer::create(File2, 8192);
- ASSERT_NO_ERROR(Buffer2OrErr.getError());
+ ASSERT_NO_ERROR(errorToErrorCode(Buffer2OrErr.takeError()));
std::unique_ptr<FileOutputBuffer> &Buffer2 = *Buffer2OrErr;
// Fill buffer with special header.
memcpy(Buffer2->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
@@ -79,17 +79,17 @@ TEST(FileOutputBuffer, Test) {
// TEST 3: Verify sizing down case.
SmallString<128> File3(TestDirectory);
- File3.append("/file3");
+ File3.append("/file3");
{
- ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+ Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
FileOutputBuffer::create(File3, 8192000);
- ASSERT_NO_ERROR(BufferOrErr.getError());
+ ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
// Start buffer with special header.
memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
// Write to end of buffer to verify it is writable.
memcpy(Buffer->getBufferEnd() - 20, "AABBCCDDEEFFGGHHIIJJ", 20);
- ASSERT_NO_ERROR(Buffer->commit());
+ ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
}
// Verify file is correct size.
@@ -100,16 +100,16 @@ TEST(FileOutputBuffer, Test) {
// TEST 4: Verify file can be made executable.
SmallString<128> File4(TestDirectory);
- File4.append("/file4");
+ File4.append("/file4");
{
- ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+ Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
FileOutputBuffer::create(File4, 8192, FileOutputBuffer::F_executable);
- ASSERT_NO_ERROR(BufferOrErr.getError());
+ ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
// Start buffer with special header.
memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
// Commit buffer.
- ASSERT_NO_ERROR(Buffer->commit());
+ ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
}
// Verify file exists and is executable.
fs::file_status Status;
diff --git a/unittests/Support/FormatVariadicTest.cpp b/unittests/Support/FormatVariadicTest.cpp
index bfbe556b31a7..ddecffdeed1d 100644
--- a/unittests/Support/FormatVariadicTest.cpp
+++ b/unittests/Support/FormatVariadicTest.cpp
@@ -578,3 +578,34 @@ TEST(FormatVariadicTest, FormatAdapter) {
// const Format cvar(1);
// EXPECT_EQ("Format", formatv("{0}", cvar).str());
}
+
+TEST(FormatVariadicTest, FormatFormatvObject) {
+ EXPECT_EQ("Format", formatv("F{0}t", formatv("o{0}a", "rm")).str());
+ EXPECT_EQ("[ ! ]", formatv("[{0,+5}]", formatv("{0,-2}", "!")).str());
+}
+
+namespace {
+struct Recorder {
+ int Copied = 0, Moved = 0;
+ Recorder() = default;
+ Recorder(const Recorder &Copy) : Copied(1 + Copy.Copied), Moved(Copy.Moved) {}
+ Recorder(const Recorder &&Move)
+ : Copied(Move.Copied), Moved(1 + Move.Moved) {}
+};
+} // namespace
+namespace llvm {
+template <> struct format_provider<Recorder> {
+ static void format(const Recorder &R, raw_ostream &OS, StringRef style) {
+ OS << R.Copied << "C " << R.Moved << "M";
+ }
+};
+} // namespace
+
+TEST(FormatVariadicTest, CopiesAndMoves) {
+ Recorder R;
+ EXPECT_EQ("0C 0M", formatv("{0}", R).str());
+ EXPECT_EQ("0C 3M", formatv("{0}", std::move(R)).str());
+ EXPECT_EQ("0C 3M", formatv("{0}", Recorder()).str());
+ EXPECT_EQ(0, R.Copied);
+ EXPECT_EQ(0, R.Moved);
+}
diff --git a/unittests/Support/GlobPatternTest.cpp b/unittests/Support/GlobPatternTest.cpp
index 44d77266db1f..d7016ab218d3 100644
--- a/unittests/Support/GlobPatternTest.cpp
+++ b/unittests/Support/GlobPatternTest.cpp
@@ -67,4 +67,13 @@ TEST_F(GlobPatternTest, Invalid) {
EXPECT_FALSE((bool)Pat1);
handleAllErrors(Pat1.takeError(), [&](ErrorInfoBase &EIB) {});
}
+
+TEST_F(GlobPatternTest, ExtSym) {
+ Expected<GlobPattern> Pat1 = GlobPattern::create("a*\xFF");
+ EXPECT_TRUE((bool)Pat1);
+ EXPECT_TRUE(Pat1->match("axxx\xFF"));
+ Expected<GlobPattern> Pat2 = GlobPattern::create("[\xFF-\xFF]");
+ EXPECT_TRUE((bool)Pat2);
+ EXPECT_TRUE(Pat2->match("\xFF"));
+}
}
diff --git a/unittests/Support/Host.cpp b/unittests/Support/Host.cpp
index 7c018ac50423..736b04c2049c 100644
--- a/unittests/Support/Host.cpp
+++ b/unittests/Support/Host.cpp
@@ -106,8 +106,17 @@ TEST(getLinuxHostCPUName, AArch64) {
"CPU part : 0x201"),
"kryo");
EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
+ "CPU part : 0x800"),
+ "cortex-a73");
+ EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
+ "CPU part : 0x801"),
+ "cortex-a73");
+ EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
"CPU part : 0xc00"),
"falkor");
+ EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
+ "CPU part : 0xc01"),
+ "saphira");
// MSM8992/4 weirdness
StringRef MSM8992ProcCpuInfo = R"(
@@ -130,6 +139,37 @@ Hardware : Qualcomm Technologies, Inc MSM8992
EXPECT_EQ(sys::detail::getHostCPUNameForARM(MSM8992ProcCpuInfo),
"cortex-a53");
+
+ // Exynos big.LITTLE weirdness
+ const std::string ExynosProcCpuInfo = R"(
+processor : 0
+Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer : 0x41
+CPU architecture: 8
+CPU variant : 0x0
+CPU part : 0xd03
+
+processor : 1
+Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer : 0x53
+CPU architecture: 8
+)";
+
+ // Verify default for Exynos.
+ EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
+ "CPU variant : 0xc\n"
+ "CPU part : 0xafe"),
+ "exynos-m1");
+ // Verify Exynos M1.
+ EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
+ "CPU variant : 0x1\n"
+ "CPU part : 0x001"),
+ "exynos-m1");
+ // Verify Exynos M2.
+ EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
+ "CPU variant : 0x4\n"
+ "CPU part : 0x001"),
+ "exynos-m2");
}
#if defined(__APPLE__)
@@ -147,8 +187,9 @@ TEST_F(HostTest, getMacOSHostVersion) {
const char *SwVersPath = "/usr/bin/sw_vers";
const char *argv[] = {SwVersPath, "-productVersion", nullptr};
StringRef OutputPath = OutputFile.str();
- const StringRef *Redirects[] = {/*STDIN=*/nullptr, /*STDOUT=*/&OutputPath,
- /*STDERR=*/nullptr};
+ const Optional<StringRef> Redirects[] = {/*STDIN=*/None,
+ /*STDOUT=*/OutputPath,
+ /*STDERR=*/None};
int RetCode = ExecuteAndWait(SwVersPath, argv, /*env=*/nullptr, Redirects);
ASSERT_EQ(0, RetCode);
diff --git a/unittests/Support/LEB128Test.cpp b/unittests/Support/LEB128Test.cpp
index 09db6dfdc593..1c9b5dbd2bd9 100644
--- a/unittests/Support/LEB128Test.cpp
+++ b/unittests/Support/LEB128Test.cpp
@@ -46,16 +46,17 @@ TEST(LEB128Test, EncodeSLEB128) {
EXPECT_SLEB128_EQ("\xc0\x00", 64, 0);
// Encode SLEB128 with some extra padding bytes
- EXPECT_SLEB128_EQ("\x80\x00", 0, 1);
- EXPECT_SLEB128_EQ("\x80\x80\x00", 0, 2);
- EXPECT_SLEB128_EQ("\xff\x80\x00", 0x7f, 1);
- EXPECT_SLEB128_EQ("\xff\x80\x80\x00", 0x7f, 2);
- EXPECT_SLEB128_EQ("\x80\x81\x00", 0x80, 1);
- EXPECT_SLEB128_EQ("\x80\x81\x80\x00", 0x80, 2);
- EXPECT_SLEB128_EQ("\xc0\x7f", -0x40, 1);
- EXPECT_SLEB128_EQ("\xc0\xff\x7f", -0x40, 2);
- EXPECT_SLEB128_EQ("\x80\xff\x7f", -0x80, 1);
- EXPECT_SLEB128_EQ("\x80\xff\xff\x7f", -0x80, 2);
+ EXPECT_SLEB128_EQ("\x80\x00", 0, 2);
+ EXPECT_SLEB128_EQ("\x80\x80\x00", 0, 3);
+ EXPECT_SLEB128_EQ("\xff\x80\x00", 0x7f, 3);
+ EXPECT_SLEB128_EQ("\xff\x80\x80\x00", 0x7f, 4);
+ EXPECT_SLEB128_EQ("\x80\x81\x00", 0x80, 3);
+ EXPECT_SLEB128_EQ("\x80\x81\x80\x00", 0x80, 4);
+ EXPECT_SLEB128_EQ("\xc0\x7f", -0x40, 2);
+
+ EXPECT_SLEB128_EQ("\xc0\xff\x7f", -0x40, 3);
+ EXPECT_SLEB128_EQ("\x80\xff\x7f", -0x80, 3);
+ EXPECT_SLEB128_EQ("\x80\xff\xff\x7f", -0x80, 4);
#undef EXPECT_SLEB128_EQ
}
@@ -93,12 +94,12 @@ TEST(LEB128Test, EncodeULEB128) {
EXPECT_ULEB128_EQ("\x81\x02", 0x101, 0);
// Encode ULEB128 with some extra padding bytes
- EXPECT_ULEB128_EQ("\x80\x00", 0, 1);
- EXPECT_ULEB128_EQ("\x80\x80\x00", 0, 2);
- EXPECT_ULEB128_EQ("\xff\x00", 0x7f, 1);
- EXPECT_ULEB128_EQ("\xff\x80\x00", 0x7f, 2);
- EXPECT_ULEB128_EQ("\x80\x81\x00", 0x80, 1);
- EXPECT_ULEB128_EQ("\x80\x81\x80\x00", 0x80, 2);
+ EXPECT_ULEB128_EQ("\x80\x00", 0, 2);
+ EXPECT_ULEB128_EQ("\x80\x80\x00", 0, 3);
+ EXPECT_ULEB128_EQ("\xff\x00", 0x7f, 2);
+ EXPECT_ULEB128_EQ("\xff\x80\x00", 0x7f, 3);
+ EXPECT_ULEB128_EQ("\x80\x81\x00", 0x80, 3);
+ EXPECT_ULEB128_EQ("\x80\x81\x80\x00", 0x80, 4);
#undef EXPECT_ULEB128_EQ
}
diff --git a/unittests/Support/ManagedStatic.cpp b/unittests/Support/ManagedStatic.cpp
index 4e2e93036a83..07e324cdfb65 100644
--- a/unittests/Support/ManagedStatic.cpp
+++ b/unittests/Support/ManagedStatic.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Config/config.h"
-#include "llvm/Support/Threading.h"
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
diff --git a/unittests/Support/MemoryTest.cpp b/unittests/Support/MemoryTest.cpp
index 140219ffd1d6..650be7b6f1dd 100644
--- a/unittests/Support/MemoryTest.cpp
+++ b/unittests/Support/MemoryTest.cpp
@@ -1,6 +1,6 @@
//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
//
-// The LLVM Compiler Infrastructure
+// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
@@ -350,16 +350,16 @@ TEST_P(MappedMemoryTest, UnalignedNear) {
// Note that Memory::MF_WRITE is not supported exclusively across
// operating systems and architectures and can imply MF_READ|MF_WRITE
unsigned MemoryFlags[] = {
- Memory::MF_READ,
- Memory::MF_WRITE,
- Memory::MF_READ|Memory::MF_WRITE,
- Memory::MF_EXEC,
- Memory::MF_READ|Memory::MF_EXEC,
- Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
- };
+ Memory::MF_READ,
+ Memory::MF_WRITE,
+ Memory::MF_READ|Memory::MF_WRITE,
+ Memory::MF_EXEC,
+ Memory::MF_READ|Memory::MF_EXEC,
+ Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
+ };
INSTANTIATE_TEST_CASE_P(AllocationTests,
- MappedMemoryTest,
- ::testing::ValuesIn(MemoryFlags),);
+ MappedMemoryTest,
+ ::testing::ValuesIn(MemoryFlags),);
} // anonymous namespace
diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp
index 3e474f33ca6d..f624626f5e53 100644
--- a/unittests/Support/Path.cpp
+++ b/unittests/Support/Path.cpp
@@ -564,6 +564,27 @@ TEST_F(FileSystemTest, RealPath) {
ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/test1"));
}
+TEST_F(FileSystemTest, TempFileKeepDiscard) {
+ // We can keep then discard.
+ auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%");
+ ASSERT_TRUE((bool)TempFileOrError);
+ fs::TempFile File = std::move(*TempFileOrError);
+ ASSERT_FALSE((bool)File.keep(TestDirectory + "/keep"));
+ ASSERT_FALSE((bool)File.discard());
+ ASSERT_TRUE(fs::exists(TestDirectory + "/keep"));
+ ASSERT_NO_ERROR(fs::remove(TestDirectory + "/keep"));
+}
+
+TEST_F(FileSystemTest, TempFileDiscardDiscard) {
+ // We can discard twice.
+ auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%");
+ ASSERT_TRUE((bool)TempFileOrError);
+ fs::TempFile File = std::move(*TempFileOrError);
+ ASSERT_FALSE((bool)File.discard());
+ ASSERT_FALSE((bool)File.discard());
+ ASSERT_FALSE(fs::exists(TestDirectory + "/keep"));
+}
+
TEST_F(FileSystemTest, TempFiles) {
// Create a temp file.
int FileDescriptor;
@@ -699,6 +720,21 @@ TEST_F(FileSystemTest, CreateDir) {
ThisDir = path::parent_path(ThisDir);
}
+ // Also verify that paths with Unix separators are handled correctly.
+ std::string LongPathWithUnixSeparators(TestDirectory.str());
+ // Add at least one subdirectory to TestDirectory, and replace slashes with
+ // backslashes
+ do {
+ LongPathWithUnixSeparators.append("/DirNameWith19Charss");
+ } while (LongPathWithUnixSeparators.size() < 260);
+ std::replace(LongPathWithUnixSeparators.begin(),
+ LongPathWithUnixSeparators.end(),
+ '\\', '/');
+ ASSERT_NO_ERROR(fs::create_directories(Twine(LongPathWithUnixSeparators)));
+ // cleanup
+ ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) +
+ "/DirNameWith19Charss"));
+
// Similarly for a relative pathname. Need to set the current directory to
// TestDirectory so that the one we create ends up in the right place.
char PreviousDir[260];
@@ -854,8 +890,8 @@ TEST_F(FileSystemTest, BrokenSymlinkDirectoryIteration) {
i != e; i.increment(ec)) {
ASSERT_NO_ERROR(ec);
- fs::file_status status;
- if (i->status(status) ==
+ ErrorOr<fs::basic_file_status> status = i->status();
+ if (status.getError() ==
std::make_error_code(std::errc::no_such_file_or_directory)) {
i.no_push();
continue;
@@ -1145,96 +1181,6 @@ TEST(Support, ReplacePathPrefix) {
EXPECT_EQ(Path, "/foo");
}
-TEST_F(FileSystemTest, PathFromFD) {
- // Create a temp file.
- int FileDescriptor;
- SmallString<64> TempPath;
- ASSERT_NO_ERROR(
- fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
- FileRemover Cleanup(TempPath);
-
- // Make sure it exists.
- ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
-
- // Try to get the path from the file descriptor
- SmallString<64> ResultPath;
- std::error_code ErrorCode =
- fs::getPathFromOpenFD(FileDescriptor, ResultPath);
-
- // If we succeeded, check that the paths are the same (modulo case):
- if (!ErrorCode) {
- // The paths returned by createTemporaryFile and getPathFromOpenFD
- // should reference the same file on disk.
- fs::UniqueID D1, D2;
- ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), D1));
- ASSERT_NO_ERROR(fs::getUniqueID(Twine(ResultPath), D2));
- ASSERT_EQ(D1, D2);
- }
-
- ::close(FileDescriptor);
-}
-
-TEST_F(FileSystemTest, PathFromFDWin32) {
- // Create a temp file.
- int FileDescriptor;
- SmallString<64> TempPath;
- ASSERT_NO_ERROR(
- fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
- FileRemover Cleanup(TempPath);
-
- // Make sure it exists.
- ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
-
- SmallVector<char, 8> ResultPath;
- std::error_code ErrorCode =
- fs::getPathFromOpenFD(FileDescriptor, ResultPath);
-
- if (!ErrorCode) {
- // Now that we know how much space is required for the path, create a path
- // buffer with exactly enough space (sans null terminator, which should not
- // be present), and call getPathFromOpenFD again to ensure that the API
- // properly handles exactly-sized buffers.
- SmallVector<char, 8> ExactSizedPath(ResultPath.size());
- ErrorCode = fs::getPathFromOpenFD(FileDescriptor, ExactSizedPath);
- ResultPath = ExactSizedPath;
- }
-
- if (!ErrorCode) {
- fs::UniqueID D1, D2;
- ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), D1));
- ASSERT_NO_ERROR(fs::getUniqueID(Twine(ResultPath), D2));
- ASSERT_EQ(D1, D2);
- }
- ::close(FileDescriptor);
-}
-
-TEST_F(FileSystemTest, PathFromFDUnicode) {
- // Create a temp file.
- int FileDescriptor;
- SmallString<64> TempPath;
-
- // Test Unicode: "<temp directory>/(pi)r^2<temp rand chars>.aleth.0"
- ASSERT_NO_ERROR(
- fs::createTemporaryFile("\xCF\x80r\xC2\xB2",
- "\xE2\x84\xB5.0", FileDescriptor, TempPath));
- FileRemover Cleanup(TempPath);
-
- // Make sure it exists.
- ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
-
- SmallVector<char, 8> ResultPath;
- std::error_code ErrorCode =
- fs::getPathFromOpenFD(FileDescriptor, ResultPath);
-
- if (!ErrorCode) {
- fs::UniqueID D1, D2;
- ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), D1));
- ASSERT_NO_ERROR(fs::getUniqueID(Twine(ResultPath), D2));
- ASSERT_EQ(D1, D2);
- }
- ::close(FileDescriptor);
-}
-
TEST_F(FileSystemTest, OpenFileForRead) {
// Create a temp file.
int FileDescriptor;
diff --git a/unittests/Support/ProcessTest.cpp b/unittests/Support/ProcessTest.cpp
index 298a0a373234..37587bf47996 100644
--- a/unittests/Support/ProcessTest.cpp
+++ b/unittests/Support/ProcessTest.cpp
@@ -42,10 +42,18 @@ TEST(ProcessTest, None) {
Optional<std::string> val(
Process::GetEnv("__LLVM_TEST_ENVIRON_NO_SUCH_VAR__"));
EXPECT_FALSE(val.hasValue());
-}
+}
#endif
#ifdef LLVM_ON_WIN32
+
+TEST(ProcessTest, EmptyVal) {
+ SetEnvironmentVariableA("__LLVM_TEST_ENVIRON_VAR__", "");
+ Optional<std::string> val(Process::GetEnv("__LLVM_TEST_ENVIRON_VAR__"));
+ EXPECT_TRUE(val.hasValue());
+ EXPECT_STREQ("", val->c_str());
+}
+
TEST(ProcessTest, Wchar) {
SetEnvironmentVariableW(L"__LLVM_TEST_ENVIRON_VAR__", L"abcdefghijklmnopqrs");
Optional<std::string> val(Process::GetEnv("__LLVM_TEST_ENVIRON_VAR__"));
diff --git a/unittests/Support/ProgramTest.cpp b/unittests/Support/ProgramTest.cpp
index f658980073da..3c272bb980c5 100644
--- a/unittests/Support/ProgramTest.cpp
+++ b/unittests/Support/ProgramTest.cpp
@@ -145,11 +145,10 @@ TEST_F(ProgramEnvTest, CreateProcessLongPath) {
LongPath.push_back('\\');
// MAX_PATH = 260
LongPath.append(260 - TestDirectory.size(), 'a');
- StringRef LongPathRef(LongPath);
std::string Error;
bool ExecutionFailed;
- const StringRef *Redirects[] = { nullptr, &LongPathRef, nullptr };
+ Optional<StringRef> Redirects[] = {None, LongPath.str(), None};
int RC = ExecuteAndWait(MyExe, ArgV, getEnviron(), Redirects,
/*secondsToWait=*/ 10, /*memoryLimit=*/ 0, &Error,
&ExecutionFailed);
@@ -192,7 +191,7 @@ TEST_F(ProgramEnvTest, CreateProcessTrailingSlash) {
#else
StringRef nul("/dev/null");
#endif
- const StringRef *redirects[] = { &nul, &nul, nullptr };
+ Optional<StringRef> redirects[] = { nul, nul, None };
int rc = ExecuteAndWait(my_exe, argv, getEnviron(), redirects,
/*secondsToWait=*/ 10, /*memoryLimit=*/ 0, &error,
&ExecutionFailed);
@@ -221,8 +220,8 @@ TEST_F(ProgramEnvTest, TestExecuteNoWait) {
std::string Error;
bool ExecutionFailed;
- ProcessInfo PI1 = ExecuteNoWait(Executable, argv, getEnviron(), nullptr, 0,
- &Error, &ExecutionFailed);
+ ProcessInfo PI1 = ExecuteNoWait(Executable, argv, getEnviron(), {}, 0, &Error,
+ &ExecutionFailed);
ASSERT_FALSE(ExecutionFailed) << Error;
ASSERT_NE(PI1.Pid, ProcessInfo::InvalidPid) << "Invalid process id";
@@ -240,8 +239,8 @@ TEST_F(ProgramEnvTest, TestExecuteNoWait) {
EXPECT_EQ(LoopCount, 1u) << "LoopCount should be 1";
- ProcessInfo PI2 = ExecuteNoWait(Executable, argv, getEnviron(), nullptr, 0,
- &Error, &ExecutionFailed);
+ ProcessInfo PI2 = ExecuteNoWait(Executable, argv, getEnviron(), {}, 0, &Error,
+ &ExecutionFailed);
ASSERT_FALSE(ExecutionFailed) << Error;
ASSERT_NE(PI2.Pid, ProcessInfo::InvalidPid) << "Invalid process id";
@@ -280,7 +279,7 @@ TEST_F(ProgramEnvTest, TestExecuteAndWaitTimeout) {
std::string Error;
bool ExecutionFailed;
int RetCode =
- ExecuteAndWait(Executable, argv, getEnviron(), nullptr, /*secondsToWait=*/1, 0,
+ ExecuteAndWait(Executable, argv, getEnviron(), {}, /*secondsToWait=*/1, 0,
&Error, &ExecutionFailed);
ASSERT_EQ(-2, RetCode);
}
@@ -292,8 +291,8 @@ TEST(ProgramTest, TestExecuteNegative) {
{
std::string Error;
bool ExecutionFailed;
- int RetCode = ExecuteAndWait(Executable, argv, nullptr, nullptr, 0, 0,
- &Error, &ExecutionFailed);
+ int RetCode = ExecuteAndWait(Executable, argv, nullptr, {}, 0, 0, &Error,
+ &ExecutionFailed);
ASSERT_TRUE(RetCode < 0) << "On error ExecuteAndWait should return 0 or "
"positive value indicating the result code";
ASSERT_TRUE(ExecutionFailed);
@@ -303,8 +302,8 @@ TEST(ProgramTest, TestExecuteNegative) {
{
std::string Error;
bool ExecutionFailed;
- ProcessInfo PI = ExecuteNoWait(Executable, argv, nullptr, nullptr, 0,
- &Error, &ExecutionFailed);
+ ProcessInfo PI = ExecuteNoWait(Executable, argv, nullptr, {}, 0, &Error,
+ &ExecutionFailed);
ASSERT_EQ(PI.Pid, ProcessInfo::InvalidPid)
<< "On error ExecuteNoWait should return an invalid ProcessInfo";
ASSERT_TRUE(ExecutionFailed);
diff --git a/unittests/Support/RegexTest.cpp b/unittests/Support/RegexTest.cpp
index 5e3ce39f0057..7e44a3c0614a 100644
--- a/unittests/Support/RegexTest.cpp
+++ b/unittests/Support/RegexTest.cpp
@@ -171,4 +171,12 @@ TEST_F(RegexTest, MatchInvalid) {
EXPECT_FALSE(r1.match("X"));
}
+// https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3727
+TEST_F(RegexTest, OssFuzz3727Regression) {
+ // Wrap in a StringRef so the NUL byte doesn't terminate the string
+ Regex r(StringRef("[[[=GS\x00[=][", 10));
+ std::string Error;
+ EXPECT_FALSE(r.isValid(Error));
+}
+
}
diff --git a/unittests/Support/ReplaceFileTest.cpp b/unittests/Support/ReplaceFileTest.cpp
index 8b16daf3233c..794f36b1f654 100644
--- a/unittests/Support/ReplaceFileTest.cpp
+++ b/unittests/Support/ReplaceFileTest.cpp
@@ -52,6 +52,21 @@ class ScopedFD {
~ScopedFD() { Process::SafelyCloseFileDescriptor(FD); }
};
+bool FDHasContent(int FD, StringRef Content) {
+ auto Buffer = MemoryBuffer::getOpenFile(FD, "", -1);
+ assert(Buffer);
+ return Buffer.get()->getBuffer() == Content;
+}
+
+bool FileHasContent(StringRef File, StringRef Content) {
+ int FD = 0;
+ auto EC = fs::openFileForRead(File, FD);
+ (void)EC;
+ assert(!EC);
+ ScopedFD EventuallyCloseIt(FD);
+ return FDHasContent(FD, Content);
+}
+
TEST(rename, FileOpenedForReadingCanBeReplaced) {
// Create unique temporary directory for this test.
SmallString<128> TestDirectory;
@@ -79,25 +94,15 @@ TEST(rename, FileOpenedForReadingCanBeReplaced) {
// We should still be able to read the old data through the existing
// descriptor.
- auto Buffer = MemoryBuffer::getOpenFile(ReadFD, TargetFileName, -1);
- ASSERT_TRUE(static_cast<bool>(Buffer));
- EXPECT_EQ(Buffer.get()->getBuffer(), "!!target!!");
+ EXPECT_TRUE(FDHasContent(ReadFD, "!!target!!"));
// The source file should no longer exist
EXPECT_FALSE(fs::exists(SourceFileName));
}
- {
- // If we obtain a new descriptor for the target file, we should find that it
- // contains the content that was in the source file.
- int ReadFD = 0;
- ASSERT_NO_ERROR(fs::openFileForRead(TargetFileName, ReadFD));
- ScopedFD EventuallyCloseIt(ReadFD);
- auto Buffer = MemoryBuffer::getOpenFile(ReadFD, TargetFileName, -1);
- ASSERT_TRUE(static_cast<bool>(Buffer));
-
- EXPECT_EQ(Buffer.get()->getBuffer(), "!!source!!");
- }
+ // If we obtain a new descriptor for the target file, we should find that it
+ // contains the content that was in the source file.
+ EXPECT_TRUE(FileHasContent(TargetFileName, "!!source!!"));
// Rename the target file back to the source file name to confirm that rename
// still works if the destination does not already exist.
@@ -110,4 +115,59 @@ TEST(rename, FileOpenedForReadingCanBeReplaced) {
ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
}
+TEST(rename, ExistingTemp) {
+ // Test that existing .tmpN files don't get deleted by the Windows
+ // sys::fs::rename implementation.
+ SmallString<128> TestDirectory;
+ ASSERT_NO_ERROR(
+ fs::createUniqueDirectory("ExistingTemp-test", TestDirectory));
+
+ SmallString<128> SourceFileName(TestDirectory);
+ path::append(SourceFileName, "source");
+
+ SmallString<128> TargetFileName(TestDirectory);
+ path::append(TargetFileName, "target");
+
+ SmallString<128> TargetTmp0FileName(TestDirectory);
+ path::append(TargetTmp0FileName, "target.tmp0");
+
+ SmallString<128> TargetTmp1FileName(TestDirectory);
+ path::append(TargetTmp1FileName, "target.tmp1");
+
+ ASSERT_NO_ERROR(CreateFileWithContent(SourceFileName, "!!source!!"));
+ ASSERT_NO_ERROR(CreateFileWithContent(TargetFileName, "!!target!!"));
+ ASSERT_NO_ERROR(CreateFileWithContent(TargetTmp0FileName, "!!target.tmp0!!"));
+
+ {
+ // Use mapped_file_region to make sure that the destination file is mmap'ed.
+ // This will cause SetInformationByHandle to fail when renaming to the
+ // destination, and we will follow the code path that tries to give target
+ // a temporary name.
+ int TargetFD;
+ std::error_code EC;
+ ASSERT_NO_ERROR(fs::openFileForRead(TargetFileName, TargetFD));
+ ScopedFD X(TargetFD);
+ sys::fs::mapped_file_region MFR(
+ TargetFD, sys::fs::mapped_file_region::readonly, 10, 0, EC);
+ ASSERT_FALSE(EC);
+
+ ASSERT_NO_ERROR(fs::rename(SourceFileName, TargetFileName));
+
+#ifdef _WIN32
+ // Make sure that target was temporarily renamed to target.tmp1 on Windows.
+ // This is signified by a permission denied error as opposed to no such file
+ // or directory when trying to open it.
+ int Tmp1FD;
+ EXPECT_EQ(errc::permission_denied,
+ fs::openFileForRead(TargetTmp1FileName, Tmp1FD));
+#endif
+ }
+
+ EXPECT_TRUE(FileHasContent(TargetTmp0FileName, "!!target.tmp0!!"));
+
+ ASSERT_NO_ERROR(fs::remove(TargetFileName));
+ ASSERT_NO_ERROR(fs::remove(TargetTmp0FileName));
+ ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+}
+
} // anonymous namespace
diff --git a/unittests/Support/ReverseIterationTest.cpp b/unittests/Support/ReverseIterationTest.cpp
new file mode 100644
index 000000000000..930bd43d11b2
--- /dev/null
+++ b/unittests/Support/ReverseIterationTest.cpp
@@ -0,0 +1,110 @@
+//===- llvm/unittest/Support/ReverseIterationTest.cpp ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+//
+// Reverse Iteration unit tests.
+//
+//===---------------------------------------------------------------------===//
+
+#include "llvm/Support/ReverseIteration.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(ReverseIterationTest, DenseMapTest1) {
+ static_assert(detail::IsPointerLike<int *>::value,
+ "int * is pointer-like");
+ static_assert(detail::IsPointerLike<uintptr_t>::value,
+ "uintptr_t is pointer-like");
+ static_assert(!detail::IsPointerLike<int>::value,
+ "int is not pointer-like");
+ static_assert(detail::IsPointerLike<void *>::value,
+ "void * is pointer-like");
+ struct IncompleteType;
+ static_assert(detail::IsPointerLike<IncompleteType *>::value,
+ "incomplete * is pointer-like");
+
+ // For a DenseMap with non-pointer-like keys, forward iteration equals
+ // reverse iteration.
+ DenseMap<int, int> Map;
+ int Keys[] = { 1, 2, 3, 4 };
+
+ // Insert keys into the DenseMap.
+ for (auto Key: Keys)
+ Map[Key] = 0;
+
+ // Note: This is the observed order of keys in the DenseMap.
+ // If there is any change in the behavior of the DenseMap, this order
+ // would need to be adjusted accordingly.
+ int IterKeys[] = { 2, 4, 1, 3 };
+
+ // Check that the DenseMap is iterated in the expected order.
+ for (const auto &Tuple : zip(Map, IterKeys))
+ ASSERT_EQ(std::get<0>(Tuple).first, std::get<1>(Tuple));
+
+ // Check operator++ (post-increment).
+ int i = 0;
+ for (auto iter = Map.begin(), end = Map.end(); iter != end; iter++, ++i)
+ ASSERT_EQ(iter->first, IterKeys[i]);
+}
+
+// Define a pointer-like int.
+struct PtrLikeInt { int value; };
+
+namespace llvm {
+
+template<> struct DenseMapInfo<PtrLikeInt *> {
+ static PtrLikeInt *getEmptyKey() {
+ static PtrLikeInt EmptyKey;
+ return &EmptyKey;
+ }
+
+ static PtrLikeInt *getTombstoneKey() {
+ static PtrLikeInt TombstoneKey;
+ return &TombstoneKey;
+ }
+
+ static int getHashValue(const PtrLikeInt *P) {
+ return P->value;
+ }
+
+ static bool isEqual(const PtrLikeInt *LHS, const PtrLikeInt *RHS) {
+ return LHS == RHS;
+ }
+};
+
+} // end namespace llvm
+
+TEST(ReverseIterationTest, DenseMapTest2) {
+ static_assert(detail::IsPointerLike<PtrLikeInt *>::value,
+ "PtrLikeInt * is pointer-like");
+
+ PtrLikeInt a = {4}, b = {8}, c = {12}, d = {16};
+ PtrLikeInt *Keys[] = { &a, &b, &c, &d };
+
+ // Insert keys into the DenseMap.
+ DenseMap<PtrLikeInt *, int> Map;
+ for (auto *Key : Keys)
+ Map[Key] = Key->value;
+
+ // Note: If there is any change in the behavior of the DenseMap,
+ // the observed order of keys would need to be adjusted accordingly.
+ if (shouldReverseIterate<PtrLikeInt *>())
+ std::reverse(&Keys[0], &Keys[4]);
+
+ // Check that the DenseMap is iterated in the expected order.
+ for (const auto &Tuple : zip(Map, Keys))
+ ASSERT_EQ(std::get<0>(Tuple).second, std::get<1>(Tuple)->value);
+
+ // Check operator++ (post-increment).
+ int i = 0;
+ for (auto iter = Map.begin(), end = Map.end(); iter != end; iter++, ++i)
+ ASSERT_EQ(iter->second, Keys[i]->value);
+}
diff --git a/unittests/Support/SourceMgrTest.cpp b/unittests/Support/SourceMgrTest.cpp
index 79c2d7278f12..2a84a89912ad 100644
--- a/unittests/Support/SourceMgrTest.cpp
+++ b/unittests/Support/SourceMgrTest.cpp
@@ -67,6 +67,16 @@ TEST_F(SourceMgrTest, BasicWarning) {
Output);
}
+TEST_F(SourceMgrTest, BasicRemark) {
+ setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+ printMessage(getLoc(4), SourceMgr::DK_Remark, "message", None, None);
+
+ EXPECT_EQ("file.in:1:5: remark: message\n"
+ "aaa bbb\n"
+ " ^\n",
+ Output);
+}
+
TEST_F(SourceMgrTest, BasicNote) {
setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
printMessage(getLoc(4), SourceMgr::DK_Note, "message", None, None);
diff --git a/unittests/Support/SpecialCaseListTest.cpp b/unittests/Support/SpecialCaseListTest.cpp
index 130848845e45..060703e102fc 100644
--- a/unittests/Support/SpecialCaseListTest.cpp
+++ b/unittests/Support/SpecialCaseListTest.cpp
@@ -51,47 +51,102 @@ TEST_F(SpecialCaseListTest, Basic) {
"src:bye\n"
"src:hi=category\n"
"src:z*=category\n");
- EXPECT_TRUE(SCL->inSection("src", "hello"));
- EXPECT_TRUE(SCL->inSection("src", "bye"));
- EXPECT_TRUE(SCL->inSection("src", "hi", "category"));
- EXPECT_TRUE(SCL->inSection("src", "zzzz", "category"));
- EXPECT_FALSE(SCL->inSection("src", "hi"));
- EXPECT_FALSE(SCL->inSection("fun", "hello"));
- EXPECT_FALSE(SCL->inSection("src", "hello", "category"));
+ EXPECT_TRUE(SCL->inSection("", "src", "hello"));
+ EXPECT_TRUE(SCL->inSection("", "src", "bye"));
+ EXPECT_TRUE(SCL->inSection("", "src", "hi", "category"));
+ EXPECT_TRUE(SCL->inSection("", "src", "zzzz", "category"));
+ EXPECT_FALSE(SCL->inSection("", "src", "hi"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "hello"));
+ EXPECT_FALSE(SCL->inSection("", "src", "hello", "category"));
+
+ EXPECT_EQ(3u, SCL->inSectionBlame("", "src", "hello"));
+ EXPECT_EQ(4u, SCL->inSectionBlame("", "src", "bye"));
+ EXPECT_EQ(5u, SCL->inSectionBlame("", "src", "hi", "category"));
+ EXPECT_EQ(6u, SCL->inSectionBlame("", "src", "zzzz", "category"));
+ EXPECT_EQ(0u, SCL->inSectionBlame("", "src", "hi"));
+ EXPECT_EQ(0u, SCL->inSectionBlame("", "fun", "hello"));
+ EXPECT_EQ(0u, SCL->inSectionBlame("", "src", "hello", "category"));
+}
+
+TEST_F(SpecialCaseListTest, CorrectErrorLineNumberWithBlankLine) {
+ std::string Error;
+ EXPECT_EQ(nullptr, makeSpecialCaseList("# This is a comment.\n"
+ "\n"
+ "[not valid\n",
+ Error));
+ EXPECT_TRUE(
+ ((StringRef)Error).startswith("malformed section header on line 3:"));
+
+ EXPECT_EQ(nullptr, makeSpecialCaseList("\n\n\n"
+ "[not valid\n",
+ Error));
+ EXPECT_TRUE(
+ ((StringRef)Error).startswith("malformed section header on line 4:"));
+}
+
+TEST_F(SpecialCaseListTest, SectionRegexErrorHandling) {
+ std::string Error;
+ EXPECT_EQ(makeSpecialCaseList("[address", Error), nullptr);
+ EXPECT_TRUE(((StringRef)Error).startswith("malformed section header "));
+
+ EXPECT_EQ(makeSpecialCaseList("[[]", Error), nullptr);
+ EXPECT_TRUE(((StringRef)Error).startswith("malformed regex for section [: "));
+
+ EXPECT_EQ(makeSpecialCaseList("src:=", Error), nullptr);
+ EXPECT_TRUE(((StringRef)Error).endswith("Supplied regexp was blank"));
+}
+
+TEST_F(SpecialCaseListTest, Section) {
+ std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:global\n"
+ "[sect1|sect2]\n"
+ "src:test1\n"
+ "[sect3*]\n"
+ "src:test2\n");
+ EXPECT_TRUE(SCL->inSection("arbitrary", "src", "global"));
+ EXPECT_TRUE(SCL->inSection("", "src", "global"));
+ EXPECT_TRUE(SCL->inSection("sect1", "src", "test1"));
+ EXPECT_FALSE(SCL->inSection("sect1-arbitrary", "src", "test1"));
+ EXPECT_FALSE(SCL->inSection("sect", "src", "test1"));
+ EXPECT_FALSE(SCL->inSection("sect1", "src", "test2"));
+ EXPECT_TRUE(SCL->inSection("sect2", "src", "test1"));
+ EXPECT_TRUE(SCL->inSection("sect3", "src", "test2"));
+ EXPECT_TRUE(SCL->inSection("sect3-arbitrary", "src", "test2"));
+ EXPECT_FALSE(SCL->inSection("", "src", "test1"));
+ EXPECT_FALSE(SCL->inSection("", "src", "test2"));
}
TEST_F(SpecialCaseListTest, GlobalInit) {
std::unique_ptr<SpecialCaseList> SCL =
makeSpecialCaseList("global:foo=init\n");
- EXPECT_FALSE(SCL->inSection("global", "foo"));
- EXPECT_FALSE(SCL->inSection("global", "bar"));
- EXPECT_TRUE(SCL->inSection("global", "foo", "init"));
- EXPECT_FALSE(SCL->inSection("global", "bar", "init"));
+ EXPECT_FALSE(SCL->inSection("", "global", "foo"));
+ EXPECT_FALSE(SCL->inSection("", "global", "bar"));
+ EXPECT_TRUE(SCL->inSection("", "global", "foo", "init"));
+ EXPECT_FALSE(SCL->inSection("", "global", "bar", "init"));
SCL = makeSpecialCaseList("type:t2=init\n");
- EXPECT_FALSE(SCL->inSection("type", "t1"));
- EXPECT_FALSE(SCL->inSection("type", "t2"));
- EXPECT_FALSE(SCL->inSection("type", "t1", "init"));
- EXPECT_TRUE(SCL->inSection("type", "t2", "init"));
+ EXPECT_FALSE(SCL->inSection("", "type", "t1"));
+ EXPECT_FALSE(SCL->inSection("", "type", "t2"));
+ EXPECT_FALSE(SCL->inSection("", "type", "t1", "init"));
+ EXPECT_TRUE(SCL->inSection("", "type", "t2", "init"));
SCL = makeSpecialCaseList("src:hello=init\n");
- EXPECT_FALSE(SCL->inSection("src", "hello"));
- EXPECT_FALSE(SCL->inSection("src", "bye"));
- EXPECT_TRUE(SCL->inSection("src", "hello", "init"));
- EXPECT_FALSE(SCL->inSection("src", "bye", "init"));
+ EXPECT_FALSE(SCL->inSection("", "src", "hello"));
+ EXPECT_FALSE(SCL->inSection("", "src", "bye"));
+ EXPECT_TRUE(SCL->inSection("", "src", "hello", "init"));
+ EXPECT_FALSE(SCL->inSection("", "src", "bye", "init"));
}
TEST_F(SpecialCaseListTest, Substring) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:hello\n"
"fun:foo\n"
"global:bar\n");
- EXPECT_FALSE(SCL->inSection("src", "othello"));
- EXPECT_FALSE(SCL->inSection("fun", "tomfoolery"));
- EXPECT_FALSE(SCL->inSection("global", "bartender"));
+ EXPECT_FALSE(SCL->inSection("", "src", "othello"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "tomfoolery"));
+ EXPECT_FALSE(SCL->inSection("", "global", "bartender"));
SCL = makeSpecialCaseList("fun:*foo*\n");
- EXPECT_TRUE(SCL->inSection("fun", "tomfoolery"));
- EXPECT_TRUE(SCL->inSection("fun", "foobar"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "tomfoolery"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "foobar"));
}
TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) {
@@ -113,7 +168,7 @@ TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) {
TEST_F(SpecialCaseListTest, EmptySpecialCaseList) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("");
- EXPECT_FALSE(SCL->inSection("foo", "bar"));
+ EXPECT_FALSE(SCL->inSection("", "foo", "bar"));
}
TEST_F(SpecialCaseListTest, MultipleBlacklists) {
@@ -124,12 +179,12 @@ TEST_F(SpecialCaseListTest, MultipleBlacklists) {
Files.push_back(makeSpecialCaseListFile("src:baz\n"
"src:*fog*\n"));
auto SCL = SpecialCaseList::createOrDie(Files);
- EXPECT_TRUE(SCL->inSection("src", "bar"));
- EXPECT_TRUE(SCL->inSection("src", "baz"));
- EXPECT_FALSE(SCL->inSection("src", "ban"));
- EXPECT_TRUE(SCL->inSection("src", "ban", "init"));
- EXPECT_TRUE(SCL->inSection("src", "tomfoolery"));
- EXPECT_TRUE(SCL->inSection("src", "tomfoglery"));
+ EXPECT_TRUE(SCL->inSection("", "src", "bar"));
+ EXPECT_TRUE(SCL->inSection("", "src", "baz"));
+ EXPECT_FALSE(SCL->inSection("", "src", "ban"));
+ EXPECT_TRUE(SCL->inSection("", "src", "ban", "init"));
+ EXPECT_TRUE(SCL->inSection("", "src", "tomfoolery"));
+ EXPECT_TRUE(SCL->inSection("", "src", "tomfoglery"));
for (auto &Path : Files)
sys::fs::remove(Path);
}
@@ -137,35 +192,35 @@ TEST_F(SpecialCaseListTest, MultipleBlacklists) {
TEST_F(SpecialCaseListTest, NoTrigramsInRules) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("fun:b.r\n"
"fun:za*az\n");
- EXPECT_TRUE(SCL->inSection("fun", "bar"));
- EXPECT_FALSE(SCL->inSection("fun", "baz"));
- EXPECT_TRUE(SCL->inSection("fun", "zakaz"));
- EXPECT_FALSE(SCL->inSection("fun", "zaraza"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "bar"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "baz"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "zakaz"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "zaraza"));
}
TEST_F(SpecialCaseListTest, NoTrigramsInARule) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("fun:*bar*\n"
"fun:za*az\n");
- EXPECT_TRUE(SCL->inSection("fun", "abara"));
- EXPECT_FALSE(SCL->inSection("fun", "bor"));
- EXPECT_TRUE(SCL->inSection("fun", "zakaz"));
- EXPECT_FALSE(SCL->inSection("fun", "zaraza"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "abara"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "bor"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "zakaz"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "zaraza"));
}
TEST_F(SpecialCaseListTest, RepetitiveRule) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("fun:*bar*bar*bar*bar*\n"
"fun:bar*\n");
- EXPECT_TRUE(SCL->inSection("fun", "bara"));
- EXPECT_FALSE(SCL->inSection("fun", "abara"));
- EXPECT_TRUE(SCL->inSection("fun", "barbarbarbar"));
- EXPECT_TRUE(SCL->inSection("fun", "abarbarbarbar"));
- EXPECT_FALSE(SCL->inSection("fun", "abarbarbar"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "bara"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "abara"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "barbarbarbar"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "abarbarbarbar"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "abarbarbar"));
}
TEST_F(SpecialCaseListTest, SpecialSymbolRule) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:*c\\+\\+abi*\n");
- EXPECT_TRUE(SCL->inSection("src", "c++abi"));
- EXPECT_FALSE(SCL->inSection("src", "c\\+\\+abi"));
+ EXPECT_TRUE(SCL->inSection("", "src", "c++abi"));
+ EXPECT_FALSE(SCL->inSection("", "src", "c\\+\\+abi"));
}
TEST_F(SpecialCaseListTest, PopularTrigram) {
@@ -173,20 +228,20 @@ TEST_F(SpecialCaseListTest, PopularTrigram) {
"fun:*aaaaa*\n"
"fun:*aaaa*\n"
"fun:*aaa*\n");
- EXPECT_TRUE(SCL->inSection("fun", "aaa"));
- EXPECT_TRUE(SCL->inSection("fun", "aaaa"));
- EXPECT_TRUE(SCL->inSection("fun", "aaaabbbaaa"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "aaa"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "aaaa"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "aaaabbbaaa"));
}
TEST_F(SpecialCaseListTest, EscapedSymbols) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:*c\\+\\+abi*\n"
"src:*hello\\\\world*\n");
- EXPECT_TRUE(SCL->inSection("src", "dir/c++abi"));
- EXPECT_FALSE(SCL->inSection("src", "dir/c\\+\\+abi"));
- EXPECT_FALSE(SCL->inSection("src", "c\\+\\+abi"));
- EXPECT_TRUE(SCL->inSection("src", "C:\\hello\\world"));
- EXPECT_TRUE(SCL->inSection("src", "hello\\world"));
- EXPECT_FALSE(SCL->inSection("src", "hello\\\\world"));
+ EXPECT_TRUE(SCL->inSection("", "src", "dir/c++abi"));
+ EXPECT_FALSE(SCL->inSection("", "src", "dir/c\\+\\+abi"));
+ EXPECT_FALSE(SCL->inSection("", "src", "c\\+\\+abi"));
+ EXPECT_TRUE(SCL->inSection("", "src", "C:\\hello\\world"));
+ EXPECT_TRUE(SCL->inSection("", "src", "hello\\world"));
+ EXPECT_FALSE(SCL->inSection("", "src", "hello\\\\world"));
}
}
diff --git a/unittests/Support/TarWriterTest.cpp b/unittests/Support/TarWriterTest.cpp
index 927c8ed9be14..901dd906ca78 100644
--- a/unittests/Support/TarWriterTest.cpp
+++ b/unittests/Support/TarWriterTest.cpp
@@ -11,6 +11,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "gtest/gtest.h"
+#include <vector>
using namespace llvm;
namespace {
@@ -37,7 +38,7 @@ struct UstarHeader {
class TarWriterTest : public ::testing::Test {};
-static UstarHeader create(StringRef Base, StringRef Filename) {
+static std::vector<uint8_t> createTar(StringRef Base, StringRef Filename) {
// Create a temporary file.
SmallString<128> Path;
std::error_code EC =
@@ -55,12 +56,25 @@ static UstarHeader create(StringRef Base, StringRef Filename) {
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(Path);
EXPECT_TRUE((bool)MBOrErr);
std::unique_ptr<MemoryBuffer> MB = std::move(*MBOrErr);
+ std::vector<uint8_t> Buf((const uint8_t *)MB->getBufferStart(),
+ (const uint8_t *)MB->getBufferEnd());
+
+ // Windows does not allow us to remove a mmap'ed files, so
+ // unmap first and then remove the temporary file.
+ MB = nullptr;
sys::fs::remove(Path);
- return *reinterpret_cast<const UstarHeader *>(MB->getBufferStart());
+
+ return Buf;
+}
+
+static UstarHeader createUstar(StringRef Base, StringRef Filename) {
+ std::vector<uint8_t> Buf = createTar(Base, Filename);
+ EXPECT_TRUE(Buf.size() >= sizeof(UstarHeader));
+ return *reinterpret_cast<const UstarHeader *>(Buf.data());
}
TEST_F(TarWriterTest, Basics) {
- UstarHeader Hdr = create("base", "file");
+ UstarHeader Hdr = createUstar("base", "file");
EXPECT_EQ("ustar", StringRef(Hdr.Magic));
EXPECT_EQ("00", StringRef(Hdr.Version, 2));
EXPECT_EQ("base/file", StringRef(Hdr.Name));
@@ -68,21 +82,98 @@ TEST_F(TarWriterTest, Basics) {
}
TEST_F(TarWriterTest, LongFilename) {
- UstarHeader Hdr1 = create(
- "012345678", std::string(99, 'x') + "/" + std::string(44, 'x') + "/foo");
- EXPECT_EQ("foo", StringRef(Hdr1.Name));
- EXPECT_EQ("012345678/" + std::string(99, 'x') + "/" + std::string(44, 'x'),
- StringRef(Hdr1.Prefix));
-
- UstarHeader Hdr2 = create(
- "012345678", std::string(99, 'x') + "/" + std::string(45, 'x') + "/foo");
- EXPECT_EQ("foo", StringRef(Hdr2.Name));
- EXPECT_EQ("012345678/" + std::string(99, 'x') + "/" + std::string(45, 'x'),
- StringRef(Hdr2.Prefix));
-
- UstarHeader Hdr3 = create(
- "012345678", std::string(99, 'x') + "/" + std::string(46, 'x') + "/foo");
- EXPECT_EQ(std::string(46, 'x') + "/foo", StringRef(Hdr3.Name));
- EXPECT_EQ("012345678/" + std::string(99, 'x'), StringRef(Hdr3.Prefix));
+ std::string x154(154, 'x');
+ std::string x155(155, 'x');
+ std::string y99(99, 'y');
+ std::string y100(100, 'y');
+
+ UstarHeader Hdr1 = createUstar("", x154 + "/" + y99);
+ EXPECT_EQ("/" + x154, StringRef(Hdr1.Prefix));
+ EXPECT_EQ(y99, StringRef(Hdr1.Name));
+
+ UstarHeader Hdr2 = createUstar("", x155 + "/" + y99);
+ EXPECT_EQ("", StringRef(Hdr2.Prefix));
+ EXPECT_EQ("", StringRef(Hdr2.Name));
+
+ UstarHeader Hdr3 = createUstar("", x154 + "/" + y100);
+ EXPECT_EQ("", StringRef(Hdr3.Prefix));
+ EXPECT_EQ("", StringRef(Hdr3.Name));
+
+ UstarHeader Hdr4 = createUstar("", x155 + "/" + y100);
+ EXPECT_EQ("", StringRef(Hdr4.Prefix));
+ EXPECT_EQ("", StringRef(Hdr4.Name));
+
+ std::string yz = "yyyyyyyyyyyyyyyyyyyy/zzzzzzzzzzzzzzzzzzzz";
+ UstarHeader Hdr5 = createUstar("", x154 + "/" + yz);
+ EXPECT_EQ("/" + x154, StringRef(Hdr5.Prefix));
+ EXPECT_EQ(yz, StringRef(Hdr5.Name));
+}
+
+TEST_F(TarWriterTest, Pax) {
+ std::vector<uint8_t> Buf = createTar("", std::string(200, 'x'));
+ EXPECT_TRUE(Buf.size() >= 1024);
+
+ auto *Hdr = reinterpret_cast<const UstarHeader *>(Buf.data());
+ EXPECT_EQ("", StringRef(Hdr->Prefix));
+ EXPECT_EQ("", StringRef(Hdr->Name));
+
+ StringRef Pax = StringRef((char *)(Buf.data() + 512), 512);
+ EXPECT_TRUE(Pax.startswith("211 path=/" + std::string(200, 'x')));
+}
+
+TEST_F(TarWriterTest, SingleFile) {
+ SmallString<128> Path;
+ std::error_code EC =
+ sys::fs::createTemporaryFile("TarWriterTest", "tar", Path);
+ EXPECT_FALSE((bool)EC);
+
+ Expected<std::unique_ptr<TarWriter>> TarOrErr = TarWriter::create(Path, "");
+ EXPECT_TRUE((bool)TarOrErr);
+ std::unique_ptr<TarWriter> Tar = std::move(*TarOrErr);
+ Tar->append("FooPath", "foo");
+ Tar.reset();
+
+ uint64_t TarSize;
+ EC = sys::fs::file_size(Path, TarSize);
+ EXPECT_FALSE((bool)EC);
+ EXPECT_EQ(TarSize, 2048ULL);
+}
+
+TEST_F(TarWriterTest, NoDuplicate) {
+ SmallString<128> Path;
+ std::error_code EC =
+ sys::fs::createTemporaryFile("TarWriterTest", "tar", Path);
+ EXPECT_FALSE((bool)EC);
+
+ Expected<std::unique_ptr<TarWriter>> TarOrErr = TarWriter::create(Path, "");
+ EXPECT_TRUE((bool)TarOrErr);
+ std::unique_ptr<TarWriter> Tar = std::move(*TarOrErr);
+ Tar->append("FooPath", "foo");
+ Tar->append("BarPath", "bar");
+ Tar.reset();
+
+ uint64_t TarSize;
+ EC = sys::fs::file_size(Path, TarSize);
+ EXPECT_FALSE((bool)EC);
+ EXPECT_EQ(TarSize, 3072ULL);
}
+
+TEST_F(TarWriterTest, Duplicate) {
+ SmallString<128> Path;
+ std::error_code EC =
+ sys::fs::createTemporaryFile("TarWriterTest", "tar", Path);
+ EXPECT_FALSE((bool)EC);
+
+ Expected<std::unique_ptr<TarWriter>> TarOrErr = TarWriter::create(Path, "");
+ EXPECT_TRUE((bool)TarOrErr);
+ std::unique_ptr<TarWriter> Tar = std::move(*TarOrErr);
+ Tar->append("FooPath", "foo");
+ Tar->append("FooPath", "bar");
+ Tar.reset();
+
+ uint64_t TarSize;
+ EC = sys::fs::file_size(Path, TarSize);
+ EXPECT_FALSE((bool)EC);
+ EXPECT_EQ(TarSize, 2048ULL);
}
+} // namespace
diff --git a/unittests/Support/TargetParserTest.cpp b/unittests/Support/TargetParserTest.cpp
index b9b725f934b3..dcef40345f05 100644
--- a/unittests/Support/TargetParserTest.cpp
+++ b/unittests/Support/TargetParserTest.cpp
@@ -25,25 +25,25 @@ const char *ARMArch[] = {
"armv7a", "armv7ve", "armv7hl", "armv7l", "armv7-r",
"armv7r", "armv7-m", "armv7m", "armv7k", "armv7s",
"armv7e-m", "armv7em", "armv8-a", "armv8", "armv8a",
- "armv8.1-a", "armv8.1a", "armv8.2-a", "armv8.2a", "armv8-r",
- "armv8r", "armv8-m.base", "armv8m.base", "armv8-m.main", "armv8m.main",
- "iwmmxt", "iwmmxt2", "xscale"};
+ "armv8.1-a", "armv8.1a", "armv8.2-a", "armv8.2a", "armv8.3-a",
+ "armv8.3a", "armv8-r", "armv8r", "armv8-m.base", "armv8m.base",
+ "armv8-m.main", "armv8m.main", "iwmmxt", "iwmmxt2", "xscale"};
bool testARMCPU(StringRef CPUName, StringRef ExpectedArch,
StringRef ExpectedFPU, unsigned ExpectedFlags,
StringRef CPUAttr) {
- unsigned ArchKind = ARM::parseCPUArch(CPUName);
- bool pass = ARM::getArchName(ArchKind).equals(ExpectedArch);
- unsigned FPUKind = ARM::getDefaultFPU(CPUName, ArchKind);
+ ARM::ArchKind AK = ARM::parseCPUArch(CPUName);
+ bool pass = ARM::getArchName(AK).equals(ExpectedArch);
+ unsigned FPUKind = ARM::getDefaultFPU(CPUName, AK);
pass &= ARM::getFPUName(FPUKind).equals(ExpectedFPU);
- unsigned ExtKind = ARM::getDefaultExtensions(CPUName, ArchKind);
+ unsigned ExtKind = ARM::getDefaultExtensions(CPUName, AK);
if (ExtKind > 1 && (ExtKind & ARM::AEK_NONE))
pass &= ((ExtKind ^ ARM::AEK_NONE) == ExpectedFlags);
else
pass &= (ExtKind == ExpectedFlags);
- pass &= ARM::getCPUAttr(ArchKind).equals(CPUAttr);
+ pass &= ARM::getCPUAttr(AK).equals(CPUAttr);
return pass;
}
@@ -218,6 +218,12 @@ TEST(TargetParserTest, testARMCPU) {
ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
"8-A"));
+ EXPECT_TRUE(testARMCPU("cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
+ ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+ ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_FP16 |
+ ARM::AEK_RAS | ARM::AEK_DOTPROD,
+ "8.2-A"));
EXPECT_TRUE(testARMCPU("cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
@@ -233,6 +239,12 @@ TEST(TargetParserTest, testARMCPU) {
ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
"8-A"));
+ EXPECT_TRUE(testARMCPU("cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
+ ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+ ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_FP16 |
+ ARM::AEK_RAS | ARM::AEK_DOTPROD,
+ "8.2-A"));
EXPECT_TRUE(testARMCPU("cyclone", "armv8-a", "crypto-neon-fp-armv8",
ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
@@ -268,11 +280,11 @@ TEST(TargetParserTest, testARMCPU) {
bool testARMArch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
unsigned ArchAttr) {
- unsigned ArchKind = ARM::parseArch(Arch);
- return (ArchKind != ARM::AK_INVALID) &
+ ARM::ArchKind AK = ARM::parseArch(Arch);
+ return (AK!= ARM::ArchKind::INVALID) &
ARM::getDefaultCPU(Arch).equals(DefaultCPU) &
- ARM::getSubArch(ArchKind).equals(SubArch) &
- (ARM::getArchAttr(ArchKind) == ArchAttr);
+ ARM::getSubArch(AK).equals(SubArch) &
+ (ARM::getArchAttr(AK) == ArchAttr);
}
TEST(TargetParserTest, testARMArch) {
@@ -343,6 +355,9 @@ TEST(TargetParserTest, testARMArch) {
testARMArch("armv8.2-a", "generic", "v8.2a",
ARMBuildAttrs::CPUArch::v8_A));
EXPECT_TRUE(
+ testARMArch("armv8.3-a", "generic", "v8.3a",
+ ARMBuildAttrs::CPUArch::v8_A));
+ EXPECT_TRUE(
testARMArch("armv8-r", "cortex-r52", "v8r",
ARMBuildAttrs::CPUArch::v8_R));
EXPECT_TRUE(
@@ -368,94 +383,118 @@ TEST(TargetParserTest, testARMArch) {
ARMBuildAttrs::CPUArch::v7));
}
-bool testARMExtension(StringRef CPUName, unsigned ArchKind, StringRef ArchExt) {
+bool testARMExtension(StringRef CPUName,ARM::ArchKind ArchKind, StringRef ArchExt) {
return ARM::getDefaultExtensions(CPUName, ArchKind) &
ARM::parseArchExt(ArchExt);
}
TEST(TargetParserTest, testARMExtension) {
- EXPECT_FALSE(testARMExtension("arm2", 0, "thumb"));
- EXPECT_FALSE(testARMExtension("arm3", 0, "thumb"));
- EXPECT_FALSE(testARMExtension("arm6", 0, "thumb"));
- EXPECT_FALSE(testARMExtension("arm7m", 0, "thumb"));
- EXPECT_FALSE(testARMExtension("strongarm", 0, "dsp"));
- EXPECT_FALSE(testARMExtension("arm7tdmi", 0, "dsp"));
- EXPECT_FALSE(testARMExtension("arm10tdmi", 0, "simd"));
- EXPECT_FALSE(testARMExtension("arm1022e", 0, "simd"));
- EXPECT_FALSE(testARMExtension("arm926ej-s", 0, "simd"));
- EXPECT_FALSE(testARMExtension("arm1136jf-s", 0, "crypto"));
- EXPECT_FALSE(testARMExtension("arm1176j-s", 0, "crypto"));
- EXPECT_FALSE(testARMExtension("arm1156t2-s", 0, "crypto"));
- EXPECT_FALSE(testARMExtension("arm1176jzf-s", 0, "crypto"));
- EXPECT_FALSE(testARMExtension("cortex-m0", 0, "crypto"));
- EXPECT_FALSE(testARMExtension("cortex-a8", 0, "crypto"));
- EXPECT_FALSE(testARMExtension("cortex-r4", 0, "crypto"));
- EXPECT_FALSE(testARMExtension("cortex-m3", 0, "crypto"));
- EXPECT_FALSE(testARMExtension("cortex-a53", 0, "ras"));
- EXPECT_FALSE(testARMExtension("cortex-r52", 0, "ras"));
- EXPECT_FALSE(testARMExtension("iwmmxt", 0, "crc"));
- EXPECT_FALSE(testARMExtension("xscale", 0, "crc"));
- EXPECT_FALSE(testARMExtension("swift", 0, "crc"));
-
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV2, "thumb"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV2A, "thumb"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV3, "thumb"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV3M, "thumb"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV4, "dsp"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV4T, "dsp"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV5T, "simd"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV5TE, "simd"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV5TEJ, "simd"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV6, "crypto"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV6K, "crypto"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV6T2, "crypto"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV6KZ, "crypto"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV6M, "crypto"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV7A, "crypto"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV7R, "crypto"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV7M, "crypto"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV7EM, "crypto"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV8A, "ras"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV8_1A, "ras"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV8_2A, "spe"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV8R, "ras"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV8MBaseline, "crc"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV8MMainline, "crc"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_IWMMXT, "crc"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_IWMMXT2, "crc"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_XSCALE, "crc"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV7S, "crypto"));
- EXPECT_FALSE(testARMExtension("generic", ARM::AK_ARMV7K, "crypto"));
+ EXPECT_FALSE(testARMExtension("arm2", ARM::ArchKind::INVALID, "thumb"));
+ EXPECT_FALSE(testARMExtension("arm3", ARM::ArchKind::INVALID, "thumb"));
+ EXPECT_FALSE(testARMExtension("arm6", ARM::ArchKind::INVALID, "thumb"));
+ EXPECT_FALSE(testARMExtension("arm7m", ARM::ArchKind::INVALID, "thumb"));
+ EXPECT_FALSE(testARMExtension("strongarm", ARM::ArchKind::INVALID, "dsp"));
+ EXPECT_FALSE(testARMExtension("arm7tdmi", ARM::ArchKind::INVALID, "dsp"));
+ EXPECT_FALSE(testARMExtension("arm10tdmi",
+ ARM::ArchKind::INVALID, "simd"));
+ EXPECT_FALSE(testARMExtension("arm1022e", ARM::ArchKind::INVALID, "simd"));
+ EXPECT_FALSE(testARMExtension("arm926ej-s",
+ ARM::ArchKind::INVALID, "simd"));
+ EXPECT_FALSE(testARMExtension("arm1136jf-s",
+ ARM::ArchKind::INVALID, "crypto"));
+ EXPECT_FALSE(testARMExtension("arm1176j-s",
+ ARM::ArchKind::INVALID, "crypto"));
+ EXPECT_FALSE(testARMExtension("arm1156t2-s",
+ ARM::ArchKind::INVALID, "crypto"));
+ EXPECT_FALSE(testARMExtension("arm1176jzf-s",
+ ARM::ArchKind::INVALID, "crypto"));
+ EXPECT_FALSE(testARMExtension("cortex-m0",
+ ARM::ArchKind::INVALID, "crypto"));
+ EXPECT_FALSE(testARMExtension("cortex-a8",
+ ARM::ArchKind::INVALID, "crypto"));
+ EXPECT_FALSE(testARMExtension("cortex-r4",
+ ARM::ArchKind::INVALID, "crypto"));
+ EXPECT_FALSE(testARMExtension("cortex-m3",
+ ARM::ArchKind::INVALID, "crypto"));
+ EXPECT_FALSE(testARMExtension("cortex-a53",
+ ARM::ArchKind::INVALID, "ras"));
+ EXPECT_FALSE(testARMExtension("cortex-r52",
+ ARM::ArchKind::INVALID, "ras"));
+ EXPECT_FALSE(testARMExtension("iwmmxt", ARM::ArchKind::INVALID, "crc"));
+ EXPECT_FALSE(testARMExtension("xscale", ARM::ArchKind::INVALID, "crc"));
+ EXPECT_FALSE(testARMExtension("swift", ARM::ArchKind::INVALID, "crc"));
+
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV2, "thumb"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV2A, "thumb"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV3, "thumb"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV3M, "thumb"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4, "dsp"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4T, "dsp"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5T, "simd"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TE, "simd"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TEJ, "simd"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6, "crypto"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6K, "crypto"));
+ EXPECT_FALSE(testARMExtension("generic",
+ ARM::ArchKind::ARMV6T2, "crypto"));
+ EXPECT_FALSE(testARMExtension("generic",
+ ARM::ArchKind::ARMV6KZ, "crypto"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6M, "crypto"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7A, "crypto"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7R, "crypto"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7M, "crypto"));
+ EXPECT_FALSE(testARMExtension("generic",
+ ARM::ArchKind::ARMV7EM, "crypto"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8A, "ras"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_1A, "ras"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "spe"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8R, "ras"));
+ EXPECT_FALSE(testARMExtension("generic",
+ ARM::ArchKind::ARMV8MBaseline, "crc"));
+ EXPECT_FALSE(testARMExtension("generic",
+ ARM::ArchKind::ARMV8MMainline, "crc"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT, "crc"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT2, "crc"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::XSCALE, "crc"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7S, "crypto"));
+ EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7K, "crypto"));
}
TEST(TargetParserTest, ARMFPUVersion) {
- for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
+ for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
FK <= ARM::FPUKind::FK_LAST;
FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
- if (FK == ARM::FK_LAST)
- EXPECT_EQ(0U, ARM::getFPUVersion(FK));
+ if (FK == ARM::FK_LAST || ARM::getFPUName(FK) == "invalid" ||
+ ARM::getFPUName(FK) == "none" || ARM::getFPUName(FK) == "softvfp")
+ EXPECT_EQ(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK));
else
- EXPECT_LE(0U, ARM::getFPUVersion(FK));
+ EXPECT_NE(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK));
}
TEST(TargetParserTest, ARMFPUNeonSupportLevel) {
for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
FK <= ARM::FPUKind::FK_LAST;
FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
- if (FK == ARM::FK_LAST)
- EXPECT_EQ(0U, ARM::getFPUNeonSupportLevel(FK));
+ if (FK == ARM::FK_LAST ||
+ ARM::getFPUName(FK).find("neon") == std::string::npos)
+ EXPECT_EQ(ARM::NeonSupportLevel::None,
+ ARM::getFPUNeonSupportLevel(FK));
else
- EXPECT_LE(0U, ARM::getFPUNeonSupportLevel(FK));
+ EXPECT_NE(ARM::NeonSupportLevel::None,
+ ARM::getFPUNeonSupportLevel(FK));
}
TEST(TargetParserTest, ARMFPURestriction) {
for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
FK <= ARM::FPUKind::FK_LAST;
- FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
- if (FK == ARM::FK_LAST)
- EXPECT_EQ(0U, ARM::getFPURestriction(FK));
+ FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) {
+ if (FK == ARM::FK_LAST ||
+ (ARM::getFPUName(FK).find("d16") == std::string::npos &&
+ ARM::getFPUName(FK).find("vfpv3xd") == std::string::npos))
+ EXPECT_EQ(ARM::FPURestriction::None, ARM::getFPURestriction(FK));
else
- EXPECT_LE(0U, ARM::getFPURestriction(FK));
+ EXPECT_NE(ARM::FPURestriction::None, ARM::getFPURestriction(FK));
+ }
}
TEST(TargetParserTest, ARMExtensionFeatures) {
@@ -491,6 +530,7 @@ TEST(TargetParserTest, ARMArchExtFeature) {
{"virt", "novirt", nullptr, nullptr},
{"fp16", "nofp16", "+fullfp16", "-fullfp16"},
{"ras", "noras", "+ras", "-ras"},
+ {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
{"os", "noos", nullptr, nullptr},
{"iwmmxt", "noiwmmxt", nullptr, nullptr},
{"iwmmxt2", "noiwmmxt2", nullptr, nullptr},
@@ -517,7 +557,7 @@ TEST(TargetParserTest, ARMparseArchEndianAndISA) {
"v6kz", "v6z", "v6zk", "v6-m", "v6m", "v6sm", "v6s-m", "v7-a",
"v7", "v7a", "v7ve", "v7hl", "v7l", "v7-r", "v7r", "v7-m",
"v7m", "v7k", "v7s", "v7e-m", "v7em", "v8-a", "v8", "v8a",
- "v8.1-a", "v8.1a", "v8.2-a", "v8.2a", "v8-r"};
+ "v8.1-a", "v8.1a", "v8.2-a", "v8.2a", "v8.3-a", "v8.3a", "v8-r"};
for (unsigned i = 0; i < array_lengthof(Arch); i++) {
std::string arm_1 = "armeb" + (std::string)(Arch[i]);
@@ -527,57 +567,60 @@ TEST(TargetParserTest, ARMparseArchEndianAndISA) {
std::string thumb_2 = "thumb" + (std::string)(Arch[i]) + "eb";
std::string thumb_3 = "thumb" + (std::string)(Arch[i]);
- EXPECT_EQ(ARM::EK_BIG, ARM::parseArchEndian(arm_1));
- EXPECT_EQ(ARM::EK_BIG, ARM::parseArchEndian(arm_2));
- EXPECT_EQ(ARM::EK_LITTLE, ARM::parseArchEndian(arm_3));
+ EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_1));
+ EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_2));
+ EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(arm_3));
- EXPECT_EQ(ARM::IK_ARM, ARM::parseArchISA(arm_1));
- EXPECT_EQ(ARM::IK_ARM, ARM::parseArchISA(arm_2));
- EXPECT_EQ(ARM::IK_ARM, ARM::parseArchISA(arm_3));
+ EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_1));
+ EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_2));
+ EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_3));
if (i >= 4) {
- EXPECT_EQ(ARM::EK_BIG, ARM::parseArchEndian(thumb_1));
- EXPECT_EQ(ARM::EK_BIG, ARM::parseArchEndian(thumb_2));
- EXPECT_EQ(ARM::EK_LITTLE, ARM::parseArchEndian(thumb_3));
+ EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_1));
+ EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_2));
+ EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(thumb_3));
- EXPECT_EQ(ARM::IK_THUMB, ARM::parseArchISA(thumb_1));
- EXPECT_EQ(ARM::IK_THUMB, ARM::parseArchISA(thumb_2));
- EXPECT_EQ(ARM::IK_THUMB, ARM::parseArchISA(thumb_3));
+ EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_1));
+ EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_2));
+ EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_3));
}
}
- EXPECT_EQ(ARM::EK_LITTLE, ARM::parseArchEndian("aarch64"));
- EXPECT_EQ(ARM::EK_BIG, ARM::parseArchEndian("aarch64_be"));
+ EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("aarch64"));
+ EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian("aarch64_be"));
- EXPECT_EQ(ARM::IK_AARCH64, ARM::parseArchISA("aarch64"));
- EXPECT_EQ(ARM::IK_AARCH64, ARM::parseArchISA("aarch64_be"));
- EXPECT_EQ(ARM::IK_AARCH64, ARM::parseArchISA("arm64"));
- EXPECT_EQ(ARM::IK_AARCH64, ARM::parseArchISA("arm64_be"));
+ EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64"));
+ EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_be"));
+ EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64"));
+ EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_be"));
}
TEST(TargetParserTest, ARMparseArchProfile) {
for (unsigned i = 0; i < array_lengthof(ARMArch); i++) {
switch (ARM::parseArch(ARMArch[i])) {
- case ARM::AK_ARMV6M:
- case ARM::AK_ARMV7M:
- case ARM::AK_ARMV7EM:
- case ARM::AK_ARMV8MMainline:
- case ARM::AK_ARMV8MBaseline:
- EXPECT_EQ(ARM::PK_M, ARM::parseArchProfile(ARMArch[i]));
- continue;
- case ARM::AK_ARMV7R:
- case ARM::AK_ARMV8R:
- EXPECT_EQ(ARM::PK_R, ARM::parseArchProfile(ARMArch[i]));
- continue;
- case ARM::AK_ARMV7A:
- case ARM::AK_ARMV7VE:
- case ARM::AK_ARMV7K:
- case ARM::AK_ARMV8A:
- case ARM::AK_ARMV8_1A:
- case ARM::AK_ARMV8_2A:
- EXPECT_EQ(ARM::PK_A, ARM::parseArchProfile(ARMArch[i]));
- continue;
+ case ARM::ArchKind::ARMV6M:
+ case ARM::ArchKind::ARMV7M:
+ case ARM::ArchKind::ARMV7EM:
+ case ARM::ArchKind::ARMV8MMainline:
+ case ARM::ArchKind::ARMV8MBaseline:
+ EXPECT_EQ(ARM::ProfileKind::M, ARM::parseArchProfile(ARMArch[i]));
+ break;
+ case ARM::ArchKind::ARMV7R:
+ case ARM::ArchKind::ARMV8R:
+ EXPECT_EQ(ARM::ProfileKind::R, ARM::parseArchProfile(ARMArch[i]));
+ break;
+ case ARM::ArchKind::ARMV7A:
+ case ARM::ArchKind::ARMV7VE:
+ case ARM::ArchKind::ARMV7K:
+ case ARM::ArchKind::ARMV8A:
+ case ARM::ArchKind::ARMV8_1A:
+ case ARM::ArchKind::ARMV8_2A:
+ case ARM::ArchKind::ARMV8_3A:
+ EXPECT_EQ(ARM::ProfileKind::A, ARM::parseArchProfile(ARMArch[i]));
+ break;
+ default:
+ EXPECT_EQ(ARM::ProfileKind::INVALID, ARM::parseArchProfile(ARMArch[i]));
+ break;
}
- EXPECT_EQ(ARM::PK_INVALID, ARM::parseArchProfile(ARMArch[i]));
}
}
@@ -592,18 +635,18 @@ TEST(TargetParserTest, ARMparseArchVersion) {
bool testAArch64CPU(StringRef CPUName, StringRef ExpectedArch,
StringRef ExpectedFPU, unsigned ExpectedFlags,
StringRef CPUAttr) {
- unsigned ArchKind = AArch64::parseCPUArch(CPUName);
- bool pass = AArch64::getArchName(ArchKind).equals(ExpectedArch);
- unsigned FPUKind = AArch64::getDefaultFPU(CPUName, ArchKind);
+ AArch64::ArchKind AK = AArch64::parseCPUArch(CPUName);
+ bool pass = AArch64::getArchName(AK).equals(ExpectedArch);
+ unsigned FPUKind = AArch64::getDefaultFPU(CPUName, AK);
pass &= AArch64::getFPUName(FPUKind).equals(ExpectedFPU);
- unsigned ExtKind = AArch64::getDefaultExtensions(CPUName, ArchKind);
+ unsigned ExtKind = AArch64::getDefaultExtensions(CPUName, AK);
if (ExtKind > 1 && (ExtKind & AArch64::AEK_NONE))
pass &= ((ExtKind ^ AArch64::AEK_NONE) == ExpectedFlags);
else
pass &= (ExtKind == ExpectedFlags);
- pass &= AArch64::getCPUAttr(ArchKind).equals(CPUAttr);
+ pass &= AArch64::getCPUAttr(AK).equals(CPUAttr);
return pass;
}
@@ -625,6 +668,12 @@ TEST(TargetParserTest, testAArch64CPU) {
AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
AArch64::AEK_SIMD, "8-A"));
EXPECT_TRUE(testAArch64CPU(
+ "cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
+ AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+ AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
+ AArch64::AEK_RDM | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
+ AArch64::AEK_RCPC, "8.2-A"));
+ EXPECT_TRUE(testAArch64CPU(
"cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
AArch64::AEK_SIMD, "8-A"));
@@ -637,6 +686,12 @@ TEST(TargetParserTest, testAArch64CPU) {
AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
AArch64::AEK_SIMD, "8-A"));
EXPECT_TRUE(testAArch64CPU(
+ "cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
+ AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+ AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
+ AArch64::AEK_RDM | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
+ AArch64::AEK_RCPC, "8.2-A"));
+ EXPECT_TRUE(testAArch64CPU(
"cyclone", "armv8-a", "crypto-neon-fp-armv8",
AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD, "8-A"));
EXPECT_TRUE(testAArch64CPU(
@@ -654,7 +709,7 @@ TEST(TargetParserTest, testAArch64CPU) {
EXPECT_TRUE(testAArch64CPU(
"falkor", "armv8-a", "crypto-neon-fp-armv8",
AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
- AArch64::AEK_SIMD, "8-A"));
+ AArch64::AEK_SIMD | AArch64::AEK_RDM, "8-A"));
EXPECT_TRUE(testAArch64CPU(
"kryo", "armv8-a", "crypto-neon-fp-armv8",
AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
@@ -662,7 +717,7 @@ TEST(TargetParserTest, testAArch64CPU) {
EXPECT_TRUE(testAArch64CPU(
"thunderx2t99", "armv8.1-a", "crypto-neon-fp-armv8",
AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_LSE |
- AArch64::AEK_FP | AArch64::AEK_SIMD, "8.1-A"));
+ AArch64::AEK_RDM | AArch64::AEK_FP | AArch64::AEK_SIMD, "8.1-A"));
EXPECT_TRUE(testAArch64CPU(
"thunderx", "armv8-a", "crypto-neon-fp-armv8",
AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_SIMD |
@@ -687,11 +742,11 @@ TEST(TargetParserTest, testAArch64CPU) {
bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
unsigned ArchAttr) {
- unsigned ArchKind = AArch64::parseArch(Arch);
- return (ArchKind != static_cast<unsigned>(AArch64::ArchKind::AK_INVALID)) &
+ AArch64::ArchKind AK = AArch64::parseArch(Arch);
+ return (AK != AArch64::ArchKind::INVALID) &
AArch64::getDefaultCPU(Arch).equals(DefaultCPU) &
- AArch64::getSubArch(ArchKind).equals(SubArch) &
- (AArch64::getArchAttr(ArchKind) == ArchAttr);
+ AArch64::getSubArch(AK).equals(SubArch) &
+ (AArch64::getArchAttr(AK) == ArchAttr);
}
TEST(TargetParserTest, testAArch64Arch) {
@@ -701,35 +756,74 @@ TEST(TargetParserTest, testAArch64Arch) {
ARMBuildAttrs::CPUArch::v8_A));
EXPECT_TRUE(testAArch64Arch("armv8.2-a", "generic", "v8.2a",
ARMBuildAttrs::CPUArch::v8_A));
+ EXPECT_TRUE(testAArch64Arch("armv8.3-a", "generic", "v8.3a",
+ ARMBuildAttrs::CPUArch::v8_A));
}
-bool testAArch64Extension(StringRef CPUName, unsigned ArchKind,
+bool testAArch64Extension(StringRef CPUName, AArch64::ArchKind AK,
StringRef ArchExt) {
- return AArch64::getDefaultExtensions(CPUName, ArchKind) &
+ return AArch64::getDefaultExtensions(CPUName, AK) &
AArch64::parseArchExt(ArchExt);
}
TEST(TargetParserTest, testAArch64Extension) {
- EXPECT_FALSE(testAArch64Extension("cortex-a35", 0, "ras"));
- EXPECT_FALSE(testAArch64Extension("cortex-a53", 0, "ras"));
- EXPECT_FALSE(testAArch64Extension("cortex-a57", 0, "ras"));
- EXPECT_FALSE(testAArch64Extension("cortex-a72", 0, "ras"));
- EXPECT_FALSE(testAArch64Extension("cortex-a73", 0, "ras"));
- EXPECT_FALSE(testAArch64Extension("cyclone", 0, "ras"));
- EXPECT_FALSE(testAArch64Extension("exynos-m1", 0, "ras"));
- EXPECT_FALSE(testAArch64Extension("kryo", 0, "ras"));
- EXPECT_FALSE(testAArch64Extension("thunderx2t99", 0, "ras"));
- EXPECT_FALSE(testAArch64Extension("thunderx", 0, "lse"));
- EXPECT_FALSE(testAArch64Extension("thunderxt81", 0, "lse"));
- EXPECT_FALSE(testAArch64Extension("thunderxt83", 0, "lse"));
- EXPECT_FALSE(testAArch64Extension("thunderxt88", 0, "lse"));
+ EXPECT_FALSE(testAArch64Extension("cortex-a35",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_FALSE(testAArch64Extension("cortex-a53",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_TRUE(testAArch64Extension("cortex-a55",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_FALSE(testAArch64Extension("cortex-a57",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_FALSE(testAArch64Extension("cortex-a72",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_FALSE(testAArch64Extension("cortex-a73",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_TRUE(testAArch64Extension("cortex-a75",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_FALSE(testAArch64Extension("cyclone",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_FALSE(testAArch64Extension("exynos-m1",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_FALSE(testAArch64Extension("exynos-m2",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_FALSE(testAArch64Extension("exynos-m3",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_TRUE(testAArch64Extension("falkor",
+ AArch64::ArchKind::INVALID, "rdm"));
+ EXPECT_FALSE(testAArch64Extension("kryo",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_TRUE(testAArch64Extension("saphira",
+ AArch64::ArchKind::INVALID, "crc"));
+ EXPECT_TRUE(testAArch64Extension("saphira",
+ AArch64::ArchKind::INVALID, "lse"));
+ EXPECT_TRUE(testAArch64Extension("saphira",
+ AArch64::ArchKind::INVALID, "rdm"));
+ EXPECT_TRUE(testAArch64Extension("saphira",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_TRUE(testAArch64Extension("saphira",
+ AArch64::ArchKind::INVALID, "rcpc"));
+ EXPECT_TRUE(testAArch64Extension("saphira",
+ AArch64::ArchKind::INVALID, "profile"));
+ EXPECT_FALSE(testAArch64Extension("saphira",
+ AArch64::ArchKind::INVALID, "fullfp16"));
+ EXPECT_FALSE(testAArch64Extension("thunderx2t99",
+ AArch64::ArchKind::INVALID, "ras"));
+ EXPECT_FALSE(testAArch64Extension("thunderx",
+ AArch64::ArchKind::INVALID, "lse"));
+ EXPECT_FALSE(testAArch64Extension("thunderxt81",
+ AArch64::ArchKind::INVALID, "lse"));
+ EXPECT_FALSE(testAArch64Extension("thunderxt83",
+ AArch64::ArchKind::INVALID, "lse"));
+ EXPECT_FALSE(testAArch64Extension("thunderxt88",
+ AArch64::ArchKind::INVALID, "lse"));
EXPECT_FALSE(testAArch64Extension(
- "generic", static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8A), "ras"));
+ "generic", AArch64::ArchKind::ARMV8A, "ras"));
EXPECT_FALSE(testAArch64Extension(
- "generic", static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_1A), "ras"));
+ "generic", AArch64::ArchKind::ARMV8_1A, "ras"));
EXPECT_FALSE(testAArch64Extension(
- "generic", static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_2A), "spe"));
+ "generic", AArch64::ArchKind::ARMV8_2A, "spe"));
}
TEST(TargetParserTest, AArch64ExtensionFeatures) {
@@ -737,7 +831,9 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
unsigned Extensions = AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
AArch64::AEK_FP | AArch64::AEK_SIMD |
AArch64::AEK_FP16 | AArch64::AEK_PROFILE |
- AArch64::AEK_RAS | AArch64::AEK_SVE;
+ AArch64::AEK_RAS | AArch64::AEK_LSE |
+ AArch64::AEK_RDM | AArch64::AEK_SVE |
+ AArch64::AEK_DOTPROD | AArch64::AEK_RCPC;
for (unsigned i = 0; i <= Extensions; i++)
EXPECT_TRUE(i == 0 ? !AArch64::getExtensionFeatures(i, Features)
@@ -746,11 +842,14 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
TEST(TargetParserTest, AArch64ArchFeatures) {
std::vector<StringRef> Features;
-
- for (unsigned AK = 0; AK < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
- AK++)
- EXPECT_TRUE((AK == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
- AK == static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
+ AArch64::ArchKind ArchKinds[] = {
+#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
+ AArch64::ArchKind::ID,
+#include "llvm/Support/AArch64TargetParser.def"
+ };
+
+ for (auto AK : ArchKinds)
+ EXPECT_TRUE((AK == AArch64::ArchKind::INVALID)
? !AArch64::getArchFeatures(AK, Features)
: AArch64::getArchFeatures(AK, Features));
}
@@ -763,7 +862,11 @@ TEST(TargetParserTest, AArch64ArchExtFeature) {
{"fp16", "nofp16", "+fullfp16", "-fullfp16"},
{"profile", "noprofile", "+spe", "-spe"},
{"ras", "noras", "+ras", "-ras"},
- {"sve", "nosve", "+sve", "-sve"}};
+ {"lse", "nolse", "+lse", "-lse"},
+ {"rdm", "nordm", "+rdm", "-rdm"},
+ {"sve", "nosve", "+sve", "-sve"},
+ {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
+ {"rcpc", "norcpc", "+rcpc", "-rcpc" }};
for (unsigned i = 0; i < array_lengthof(ArchExt); i++) {
EXPECT_EQ(StringRef(ArchExt[i][2]),
diff --git a/unittests/Support/YAMLIOTest.cpp b/unittests/Support/YAMLIOTest.cpp
index 120773a0c8dd..9caff85a5963 100644
--- a/unittests/Support/YAMLIOTest.cpp
+++ b/unittests/Support/YAMLIOTest.cpp
@@ -860,7 +860,7 @@ namespace yaml {
return "malformed by";
}
}
- static bool mustQuote(StringRef) { return true; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
};
}
}
@@ -1064,7 +1064,7 @@ namespace yaml {
return StringRef();
}
- static bool mustQuote(StringRef) { return false; }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};
template <> struct ScalarTraits<MyString> {
@@ -1075,7 +1075,9 @@ namespace yaml {
static StringRef input(StringRef S, void *Ctx, MyString &V) {
return Impl::input(S, Ctx, V.value);
}
- static bool mustQuote(StringRef S) { return Impl::mustQuote(S); }
+ static QuotingType mustQuote(StringRef S) {
+ return Impl::mustQuote(S);
+ }
};
}
}
@@ -2232,7 +2234,7 @@ struct ScalarTraits<FlowSeq> {
return "";
}
- static bool mustQuote(StringRef S) { return false; }
+ static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
};
}
}
@@ -2455,3 +2457,87 @@ TEST(YAMLIO, InvalidInput) {
yin >> Data;
EXPECT_TRUE((bool)yin.error());
}
+
+TEST(YAMLIO, TestEscapedSingleQuote) {
+ std::string Id = "@abc@";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("'@abc@'", out);
+}
+
+TEST(YAMLIO, TestEscapedNoQuote) {
+ std::string Id = "abc/";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("abc/", out);
+}
+
+TEST(YAMLIO, TestEscapedDoubleQuoteNonPrintable) {
+ std::string Id = "\01@abc@";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("\"\\x01@abc@\"", out);
+}
+
+TEST(YAMLIO, TestEscapedDoubleQuoteInsideSingleQuote) {
+ std::string Id = "abc\"fdf";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("'abc\"fdf'", out);
+}
+
+TEST(YAMLIO, TestEscapedDoubleQuoteInsideDoubleQuote) {
+ std::string Id = "\01bc\"fdf";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("\"\\x01bc\\\"fdf\"", out);
+}
+
+TEST(YAMLIO, TestEscapedSingleQuoteInsideSingleQuote) {
+ std::string Id = "abc'fdf";
+
+ std::string out;
+ llvm::raw_string_ostream ostr(out);
+ Output xout(ostr, nullptr, 0);
+
+ llvm::yaml::EmptyContext Ctx;
+ yamlize(xout, Id, true, Ctx);
+
+ ostr.flush();
+ EXPECT_EQ("'abc''fdf'", out);
+}
diff --git a/unittests/Support/YAMLParserTest.cpp b/unittests/Support/YAMLParserTest.cpp
index d411a286830b..7962f3ca1ad1 100644
--- a/unittests/Support/YAMLParserTest.cpp
+++ b/unittests/Support/YAMLParserTest.cpp
@@ -180,6 +180,7 @@ TEST(YAMLParser, HandlesEndOfFileGracefully) {
}
TEST(YAMLParser, HandlesNullValuesInKeyValueNodesGracefully) {
+ ExpectParseError("KeyValueNode with null key", "? \"\n:");
ExpectParseError("KeyValueNode with null value", "test: '");
}