зеркало из https://github.com/microsoft/msquic.git
Onboard core unit tests to gtest (#136)
Co-authored-by: Nick Banks <nibanks@microsoft.com>
This commit is contained in:
Родитель
8ba6e449e7
Коммит
02f0b265df
|
@ -195,6 +195,7 @@ if(QUIC_BUILD_TEST)
|
|||
endif()
|
||||
add_subdirectory(submodules/googletest)
|
||||
|
||||
add_subdirectory(src/core/unittest)
|
||||
add_subdirectory(src/test/lib)
|
||||
add_subdirectory(src/test/bin)
|
||||
endif()
|
||||
|
|
|
@ -133,44 +133,49 @@ $RunTest = Join-Path $RootDir ".azure/scripts/run-gtest.ps1"
|
|||
|
||||
# Path to the msquictest exectuable.
|
||||
$MsQuicTest = $null
|
||||
$MsQuicCoreTest = $null
|
||||
if ($IsWindows) {
|
||||
$MsQuicTest = Join-Path $RootDir "\artifacts\windows\$($Arch)_$($Config)_$($Tls)\msquictest.exe"
|
||||
$MsQuicCoreTest = Join-Path $RootDir "\artifacts\windows\$($Arch)_$($Config)_$($Tls)\msquiccoretest.exe"
|
||||
} else {
|
||||
$MsQuicTest = Join-Path $RootDir "/artifacts/linux/$($Arch)_$($Config)_$($Tls)/msquictest"
|
||||
$MsQuicCoreTest = Join-Path $RootDir "/artifacts/linux/$($Arch)_$($Config)_$($Tls)/msquiccoretest"
|
||||
}
|
||||
|
||||
# Build up all the arguments to pass to the Powershell script.
|
||||
$Arguments = "-Path $($MsQuicTest) -ExecutionMode $($ExecutionMode) -IsolationMode $($IsolationMode)"
|
||||
$TestArguments = "-ExecutionMode $($ExecutionMode) -IsolationMode $($IsolationMode)"
|
||||
|
||||
if ("" -ne $Filter) {
|
||||
$Arguments += " -Filter $($Filter)"
|
||||
$TestArguments += " -Filter $($Filter)"
|
||||
}
|
||||
if ($ListTestCases) {
|
||||
$Arguments += " -ListTestCases"
|
||||
$TestArguments += " -ListTestCases"
|
||||
}
|
||||
if ($KeepOutputOnSuccess) {
|
||||
$Arguments += " -KeepOutputOnSuccess"
|
||||
$TestArguments += " -KeepOutputOnSuccess"
|
||||
}
|
||||
if ($GenerateXmlResults) {
|
||||
$Arguments += " -GenerateXmlResults"
|
||||
$TestArguments += " -GenerateXmlResults"
|
||||
}
|
||||
if ($Debugger) {
|
||||
$Arguments += " -Debugger"
|
||||
$TestArguments += " -Debugger"
|
||||
}
|
||||
if ($InitialBreak) {
|
||||
$Arguments += " -InitialBreak"
|
||||
$TestArguments += " -InitialBreak"
|
||||
}
|
||||
if ($BreakOnFailure) {
|
||||
$Arguments += " -BreakOnFailure"
|
||||
$TestArguments += " -BreakOnFailure"
|
||||
}
|
||||
if ("None" -ne $LogProfile) {
|
||||
$Arguments += " -LogProfile $($LogProfile)"
|
||||
$TestArguments += " -LogProfile $($LogProfile)"
|
||||
}
|
||||
if ($ConvertLogs) {
|
||||
$Arguments += " -ConvertLogs"
|
||||
$TestArguments += " -ConvertLogs"
|
||||
}
|
||||
if ($CompressOutput) {
|
||||
$Arguments += " -CompressOutput"
|
||||
$TestArguments += " -CompressOutput"
|
||||
}
|
||||
|
||||
# Run the script.
|
||||
Invoke-Expression ($RunTest + " " + $Arguments)
|
||||
Invoke-Expression ($RunTest + " -Path $($MsQuicTest) " + $TestArguments)
|
||||
Invoke-Expression ($RunTest + " -Path $($MsQuicCoreTest) " + $TestArguments)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src/core)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/submodules/googletest/googletest/include)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QUIC_CXX_FLAGS}")
|
||||
|
||||
set(
|
||||
SOURCES
|
||||
FrameTest.cpp
|
||||
PacketNumberTest.cpp
|
||||
RangeTest.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
add_executable(msquiccoretest ${SOURCES})
|
||||
|
||||
target_link_libraries(msquiccoretest msquic gtest)
|
||||
|
||||
add_test(msquiccoretest msquiccoretest)
|
|
@ -9,83 +9,67 @@ Abstract:
|
|||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#define LOG_ONLY_FAILURES
|
||||
#define INLINE_TEST_METHOD_MARKUP
|
||||
#include <wextestclass.h>
|
||||
#include <logcontroller.h>
|
||||
#include "main.h"
|
||||
|
||||
#ifdef QUIC_LOGS_WPP
|
||||
#include "frametest.tmh"
|
||||
#endif
|
||||
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::Common;
|
||||
|
||||
#define VERIFY_QUIC_SUCCESS(result, ...) \
|
||||
VERIFY_ARE_EQUAL(QUIC_STATUS_SUCCESS, result, __VA_ARGS__)
|
||||
|
||||
struct FrameTest : public WEX::TestClass<FrameTest>
|
||||
uint64_t Encode(uint64_t Value)
|
||||
{
|
||||
BEGIN_TEST_CLASS(FrameTest)
|
||||
END_TEST_CLASS()
|
||||
uint64_t Encoded = 0;
|
||||
EXPECT_NE(QuicVarIntEncode(Value, (uint8_t*)&Encoded), nullptr);
|
||||
return Encoded;
|
||||
}
|
||||
|
||||
uint64_t Encode(uint64_t Value)
|
||||
{
|
||||
uint64_t Encoded = 0;
|
||||
VERIFY_IS_NOT_NULL(QuicVarIntEncode(Value, (uint8_t*)&Encoded));
|
||||
return Encoded;
|
||||
uint64_t Decode(uint64_t Encoded)
|
||||
{
|
||||
uint64_t Decoded;
|
||||
uint16_t Offset = 0;
|
||||
EXPECT_NE(QuicVarIntDecode(sizeof(Encoded), (uint8_t*)&Encoded, &Offset, &Decoded), (BOOLEAN)0);
|
||||
return Decoded;
|
||||
}
|
||||
|
||||
TEST(FrameTest, WellKnownEncode)
|
||||
{
|
||||
TEST_EQUAL(Encode(0), 0);
|
||||
TEST_EQUAL(Encode(0x3F), 0x3F);
|
||||
TEST_EQUAL(Encode(0x40), 0x4040);
|
||||
TEST_EQUAL(Encode(0x3FFF), 0xFF7F);
|
||||
TEST_EQUAL(Encode(0x4000), 0x400080);
|
||||
TEST_EQUAL(Encode(0x3FFFFFFF), 0xFFFFFFBF);
|
||||
TEST_EQUAL(Encode(0x40000000), 0x40000000C0ULL);
|
||||
TEST_EQUAL(Encode(0x3FFFFFFFFFFFFFFF), 0xFFFFFFFFFFFFFFFF);
|
||||
}
|
||||
|
||||
TEST(FrameTest, WellKnownDecode)
|
||||
{
|
||||
TEST_EQUAL(Decode(0), 0);
|
||||
TEST_EQUAL(Decode(0x3F), 0x3F);
|
||||
TEST_EQUAL(Decode(0x4040), 0x40);
|
||||
TEST_EQUAL(Decode(0xFF7F), 0x3FFF);
|
||||
TEST_EQUAL(Decode(0x400080), 0x4000);
|
||||
TEST_EQUAL(Decode(0xFFFFFFBF), 0x3FFFFFFF);
|
||||
TEST_EQUAL(Decode(0x40000000C0ULL), 0x40000000);
|
||||
TEST_EQUAL(Decode(0xFFFFFFFFFFFFFFFF), 0x3FFFFFFFFFFFFFFFULL);
|
||||
}
|
||||
|
||||
TEST(FrameTest, RandomEncodeDecode)
|
||||
{
|
||||
for (uint32_t i = 0; i < 1000; i++) {
|
||||
|
||||
//
|
||||
// Generate a random value and make sure the top 2 bits aren't set.
|
||||
//
|
||||
uint64_t Value;
|
||||
TEST_QUIC_SUCCEEDED(QuicRandom(sizeof(Value), &Value));
|
||||
Value &= ~(3ULL << 62);
|
||||
|
||||
//
|
||||
// Encode the value, decode the result and compare to the original value.
|
||||
//
|
||||
uint64_t Encoded = Encode(Value);
|
||||
uint64_t Decoded = Decode(Encoded);
|
||||
TEST_EQUAL(Value, Decoded);
|
||||
}
|
||||
|
||||
uint64_t Decode(uint64_t Encoded)
|
||||
{
|
||||
uint64_t Decoded;
|
||||
UINT16 Offset = 0;
|
||||
VERIFY_IS_TRUE(QuicVarIntDecode(sizeof(Encoded), (uint8_t*)&Encoded, &Offset, &Decoded));
|
||||
return Decoded;
|
||||
}
|
||||
|
||||
TEST_METHOD(WellKnownEncode)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(Encode(0), 0);
|
||||
VERIFY_ARE_EQUAL(Encode(0x3F), 0x3F);
|
||||
VERIFY_ARE_EQUAL(Encode(0x40), 0x4040);
|
||||
VERIFY_ARE_EQUAL(Encode(0x3FFF), 0xFF7F);
|
||||
VERIFY_ARE_EQUAL(Encode(0x4000), 0x400080);
|
||||
VERIFY_ARE_EQUAL(Encode(0x3FFFFFFF), 0xFFFFFFBF);
|
||||
VERIFY_ARE_EQUAL(Encode(0x40000000), 0x40000000C0ULL);
|
||||
VERIFY_ARE_EQUAL(Encode(0x3FFFFFFFFFFFFFFF), 0xFFFFFFFFFFFFFFFF);
|
||||
}
|
||||
|
||||
TEST_METHOD(WellKnownDecode)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(Decode(0), 0);
|
||||
VERIFY_ARE_EQUAL(Decode(0x3F), 0x3F);
|
||||
VERIFY_ARE_EQUAL(Decode(0x4040), 0x40);
|
||||
VERIFY_ARE_EQUAL(Decode(0xFF7F), 0x3FFF);
|
||||
VERIFY_ARE_EQUAL(Decode(0x400080), 0x4000);
|
||||
VERIFY_ARE_EQUAL(Decode(0xFFFFFFBF), 0x3FFFFFFF);
|
||||
VERIFY_ARE_EQUAL(Decode(0x40000000C0ULL), 0x40000000);
|
||||
VERIFY_ARE_EQUAL(Decode(0xFFFFFFFFFFFFFFFF), 0x3FFFFFFFFFFFFFFFULL);
|
||||
}
|
||||
|
||||
TEST_METHOD(RandomEncodeDecode)
|
||||
{
|
||||
for (uint32_t i = 0; i < 1000; i++) {
|
||||
|
||||
//
|
||||
// Generate a random value and make sure the top 2 bits aren't set.
|
||||
//
|
||||
uint64_t Value;
|
||||
VERIFY_QUIC_SUCCESS(QuicRandom(sizeof(Value), &Value));
|
||||
Value &= ~(3ULL << 62);
|
||||
|
||||
//
|
||||
// Encode the value, decode the result and compare to the original value.
|
||||
//
|
||||
uint64_t Encoded = Encode(Value);
|
||||
uint64_t Decoded = Decode(Encoded);
|
||||
VERIFY_ARE_EQUAL(Value, Decoded);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -9,76 +9,60 @@ Abstract:
|
|||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#define LOG_ONLY_FAILURES
|
||||
#define INLINE_TEST_METHOD_MARKUP
|
||||
#include <wextestclass.h>
|
||||
#include <logcontroller.h>
|
||||
#include "main.h"
|
||||
|
||||
#ifdef QUIC_LOGS_WPP
|
||||
#include "frametest.tmh"
|
||||
#endif
|
||||
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::Common;
|
||||
struct DecompressEntry {
|
||||
uint64_t HighestReceived;
|
||||
uint8_t CompressedBytes;
|
||||
uint64_t Compressed;
|
||||
uint64_t PacketNumber;
|
||||
};
|
||||
|
||||
#define VERIFY_QUIC_SUCCESS(result, ...) \
|
||||
VERIFY_ARE_EQUAL(QUIC_STATUS_SUCCESS, result, __VA_ARGS__)
|
||||
|
||||
struct PacketNumberTest : public WEX::TestClass<PacketNumberTest>
|
||||
TEST(PacketNumberTest, WellKnownDecompress)
|
||||
{
|
||||
BEGIN_TEST_CLASS(PacketNumberTest)
|
||||
END_TEST_CLASS()
|
||||
|
||||
struct DecompressEntry {
|
||||
uint64_t HighestReceived;
|
||||
UINT8 CompressedBytes;
|
||||
uint64_t Compressed;
|
||||
uint64_t PacketNumber;
|
||||
DecompressEntry Entries[] = {
|
||||
{ 63, 1, 0, 0 },
|
||||
{ 0x10000, 2, 0x8000, 0x18000},
|
||||
{ 0xFFFE, 2, 0x8000, 0x8000 },
|
||||
{ 0xFFFF, 2, 0x8000, 0x8000 },
|
||||
{ 0xDEADBEEF, 4, 0xDEADBEF0, 0xDEADBEF0 },
|
||||
{ 0xDEADBEEF, 4, 0xDEADBEEF, 0xDEADBEEF },
|
||||
{ 0xDEADBEEF, 4, 0xDEADBEEE, 0xDEADBEEE },
|
||||
{ 0xDEADBEEF, 4, 0, 0x100000000ull },
|
||||
{ 0xDEADBEEF, 4, 1, 0x100000001ull },
|
||||
{ 0xDEADBEEF, 4, 0x10000000, 0x110000000ull },
|
||||
{ 0xDEADBEEF, 4, 0x5EADBEEE, 0x15EADBEEEull },
|
||||
{ 0xDEADBEEF, 4, 0x5EADBEF0, 0x5EADBEF0ull },
|
||||
{ 0xDEADBEEF, 4, 0x5EADBEEF, 0x15EADBEEFull },
|
||||
{ 0x5EADBEEF, 4, 0xDEADBEEF, 0xDEADBEEFull },
|
||||
{ 0x15EADBEEF, 4, 0xDEADBEEF, 0x1DEADBEEFull },
|
||||
{ 0xDEADBEEF, 2, 0xBEF0, 0xDEADBEF0 },
|
||||
{ 0xDEADBEEF, 2, 0xBEEF, 0xDEADBEEF },
|
||||
{ 0xDEADBEEF, 2, 0xBEEE, 0xDEADBEEE },
|
||||
{ 0xDEADBEEF, 2, 0x3EEE, 0xDEAE3EEEull },
|
||||
{ 0xDEADBEEF, 2, 0x3EEF, 0xDEAE3EEFull },
|
||||
{ 0xDEADBEEF, 2, 0x3EF0, 0xDEAD3EF0ull },
|
||||
{ 0xDEADBEEF, 1, 0xF0, 0xDEADBEF0 },
|
||||
{ 0xDEADBEEF, 1, 0xEF, 0xDEADBEEF },
|
||||
{ 0xDEADBEEF, 1, 0xEE, 0xDEADBEEE },
|
||||
{ 0xDEADBEEF, 1, 0x7F, 0xDEADBE7Full },
|
||||
{ 0xDEADBE71, 1, 0xEF, 0xDEADBEEFull },
|
||||
{ 0xDEADBE70, 1, 0xEF, 0xDEADBEEFull },
|
||||
{ 0xDEADBE6F, 1, 0xEF, 0xDEADBEEFull },
|
||||
{ 0xDEADBE6E, 1, 0xEF, 0xDEADBDEFull },
|
||||
{ 0x35, 4, 0xFFFFFFFFull, 0xFFFFFFFFull }
|
||||
};
|
||||
|
||||
TEST_METHOD(WellKnownDecompress)
|
||||
{
|
||||
DecompressEntry Entries[] = {
|
||||
{ 63, 1, 0, 0 },
|
||||
{ 0x10000, 2, 0x8000, 0x18000},
|
||||
{ 0xFFFE, 2, 0x8000, 0x8000 },
|
||||
{ 0xFFFF, 2, 0x8000, 0x8000 },
|
||||
{ 0xDEADBEEF, 4, 0xDEADBEF0, 0xDEADBEF0 },
|
||||
{ 0xDEADBEEF, 4, 0xDEADBEEF, 0xDEADBEEF },
|
||||
{ 0xDEADBEEF, 4, 0xDEADBEEE, 0xDEADBEEE },
|
||||
{ 0xDEADBEEF, 4, 0, 0x100000000ull },
|
||||
{ 0xDEADBEEF, 4, 1, 0x100000001ull },
|
||||
{ 0xDEADBEEF, 4, 0x10000000, 0x110000000ull },
|
||||
{ 0xDEADBEEF, 4, 0x5EADBEEE, 0x15EADBEEEull },
|
||||
{ 0xDEADBEEF, 4, 0x5EADBEF0, 0x5EADBEF0ull },
|
||||
{ 0xDEADBEEF, 4, 0x5EADBEEF, 0x15EADBEEFull },
|
||||
{ 0x5EADBEEF, 4, 0xDEADBEEF, 0xDEADBEEFull },
|
||||
{ 0x15EADBEEF, 4, 0xDEADBEEF, 0x1DEADBEEFull },
|
||||
{ 0xDEADBEEF, 2, 0xBEF0, 0xDEADBEF0 },
|
||||
{ 0xDEADBEEF, 2, 0xBEEF, 0xDEADBEEF },
|
||||
{ 0xDEADBEEF, 2, 0xBEEE, 0xDEADBEEE },
|
||||
{ 0xDEADBEEF, 2, 0x3EEE, 0xDEAE3EEEull },
|
||||
{ 0xDEADBEEF, 2, 0x3EEF, 0xDEAE3EEFull },
|
||||
{ 0xDEADBEEF, 2, 0x3EF0, 0xDEAD3EF0ull },
|
||||
{ 0xDEADBEEF, 1, 0xF0, 0xDEADBEF0 },
|
||||
{ 0xDEADBEEF, 1, 0xEF, 0xDEADBEEF },
|
||||
{ 0xDEADBEEF, 1, 0xEE, 0xDEADBEEE },
|
||||
{ 0xDEADBEEF, 1, 0x7F, 0xDEADBE7Full },
|
||||
{ 0xDEADBE71, 1, 0xEF, 0xDEADBEEFull },
|
||||
{ 0xDEADBE70, 1, 0xEF, 0xDEADBEEFull },
|
||||
{ 0xDEADBE6F, 1, 0xEF, 0xDEADBEEFull },
|
||||
{ 0xDEADBE6E, 1, 0xEF, 0xDEADBDEFull },
|
||||
{ 0x35, 4, 0xFFFFFFFFull, 0xFFFFFFFFull }
|
||||
};
|
||||
|
||||
for (UINT8 i = 0; i < ARRAYSIZE(Entries); i++) {
|
||||
VERIFY_ARE_EQUAL(
|
||||
QuicPktNumDecompress(
|
||||
Entries[i].HighestReceived + 1,
|
||||
Entries[i].Compressed,
|
||||
Entries[i].CompressedBytes),
|
||||
Entries[i].PacketNumber);
|
||||
}
|
||||
for (uint8_t i = 0; i < ARRAYSIZE(Entries); i++) {
|
||||
TEST_EQUAL(
|
||||
QuicPktNumDecompress(
|
||||
Entries[i].HighestReceived + 1,
|
||||
Entries[i].Compressed,
|
||||
Entries[i].CompressedBytes),
|
||||
Entries[i].PacketNumber);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -5,39 +5,28 @@
|
|||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
#define LOG_ONLY_FAILURES
|
||||
#define INLINE_TEST_METHOD_MARKUP
|
||||
#include <wextestclass.h>
|
||||
#include <logcontroller.h>
|
||||
#include "main.h"
|
||||
|
||||
#ifdef QUIC_LOGS_WPP
|
||||
#include "main.tmh"
|
||||
#endif
|
||||
|
||||
using namespace WEX::Common;
|
||||
extern "C" _IRQL_requires_max_(PASSIVE_LEVEL) void QuicTraceRundown(void) { }
|
||||
|
||||
BEGIN_MODULE()
|
||||
MODULE_PROPERTY(L"BinaryUnderTest", L"core.lib")
|
||||
MODULE_PROPERTY(L"Description", L"Tests the QUIC core user-mode library")
|
||||
MODULE_PROPERTY(L"Owner", L"nibanks")
|
||||
END_MODULE()
|
||||
|
||||
extern "C" void QuicTraceRundown(void) { }
|
||||
|
||||
MODULE_SETUP(GlobalTestSetup)
|
||||
{
|
||||
QuicPlatformSystemLoad();
|
||||
if (QUIC_FAILED(QuicPlatformInitialize())) {
|
||||
QuicPlatformSystemUnload();
|
||||
return false;
|
||||
class QuicCoreTestEnvironment : public ::testing::Environment {
|
||||
public:
|
||||
void SetUp() override {
|
||||
QuicPlatformSystemLoad();
|
||||
ASSERT_TRUE(QUIC_SUCCEEDED(QuicPlatformInitialize()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void TearDown() override {
|
||||
QuicPlatformUninitialize();
|
||||
QuicPlatformSystemUnload();
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_CLEANUP(GlobalTestCleanup)
|
||||
{
|
||||
QuicPlatformUninitialize();
|
||||
QuicPlatformSystemUnload();
|
||||
return true;
|
||||
int main(int argc, char** argv) {
|
||||
::testing::AddGlobalTestEnvironment(new QuicCoreTestEnvironment);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
Licensed under the MIT License.
|
||||
|
||||
--*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#undef min // gtest headers conflict with previous definitions of min/max.
|
||||
#undef max
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#define TEST_EQUAL(__expected, __condition) ASSERT_EQ(__expected, __condition)
|
||||
|
||||
#define TEST_NOT_EQUAL(__expected, __condition) ASSERT_NE(__expected, __condition)
|
||||
|
||||
#define TEST_TRUE(__condition) ASSERT_TRUE(__condition)
|
||||
|
||||
#define TEST_FALSE(__condition) ASSERT_FALSE(__condition)
|
||||
|
||||
#define TEST_QUIC_STATUS(__expected, __condition) ASSERT_EQ(__expected, __condition)
|
||||
|
||||
#define TEST_QUIC_SUCCEEDED(__condition) ASSERT_FALSE(QUIC_FAILED(__condition))
|
|
@ -99,7 +99,12 @@ QuicPlatformUninitialize(
|
|||
#define SIZEOF_STRUCT_MEMBER(StructType, StructMember) sizeof(((StructType *)0)->StructMember)
|
||||
#define TYPEOF_STRUCT_MEMBER(StructType, StructMember) typeof(((StructType *)0)->StructMember)
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 7
|
||||
#define __fallthrough __attribute__((fallthrough))
|
||||
#else
|
||||
#define __fallthrough // fall through
|
||||
#endif /* __GNUC__ >= 7 */
|
||||
|
||||
|
||||
//
|
||||
// Interlocked implementations.
|
||||
|
|
Загрузка…
Ссылка в новой задаче