Skip to content

Commit 9cfda6c

Browse files
committed
Fixed VS2019 /W4 warnings with and without C++17 language suport (issue cameron314#211)
1 parent 7bb34c9 commit 9cfda6c

File tree

6 files changed

+89
-56
lines changed

6 files changed

+89
-56
lines changed

build/msvc16/fuzztests.vcxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
<ClCompile>
103103
<PrecompiledHeader>
104104
</PrecompiledHeader>
105-
<WarningLevel>Level3</WarningLevel>
105+
<WarningLevel>Level4</WarningLevel>
106106
<Optimization>Disabled</Optimization>
107107
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
108108
<DisableSpecificWarnings>4800</DisableSpecificWarnings>
@@ -128,7 +128,7 @@
128128
</ItemDefinitionGroup>
129129
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
130130
<ClCompile>
131-
<WarningLevel>Level3</WarningLevel>
131+
<WarningLevel>Level4</WarningLevel>
132132
<PrecompiledHeader>
133133
</PrecompiledHeader>
134134
<Optimization>MaxSpeed</Optimization>

build/msvc16/unittests.vcxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
<ClCompile>
9292
<PrecompiledHeader>
9393
</PrecompiledHeader>
94-
<WarningLevel>Level3</WarningLevel>
94+
<WarningLevel>Level4</WarningLevel>
9595
<Optimization>Disabled</Optimization>
9696
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
9797
<DisableSpecificWarnings>4146</DisableSpecificWarnings>
@@ -117,7 +117,7 @@
117117
</ItemDefinitionGroup>
118118
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
119119
<ClCompile>
120-
<WarningLevel>Level3</WarningLevel>
120+
<WarningLevel>Level4</WarningLevel>
121121
<PrecompiledHeader>
122122
</PrecompiledHeader>
123123
<Optimization>MaxSpeed</Optimization>

concurrentqueue.h

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@
4343
#endif
4444
#endif
4545

46+
#if defined(_MSC_VER) && (!defined(_HAS_CXX17) || !_HAS_CXX17)
47+
// VS2019 with /W4 warns about constant conditional expressions but unless /std=c++17 or higher
48+
// does not support `if constexpr`, so we have no choice but to simply disable the warning
49+
#pragma warning(push)
50+
#pragma warning(disable: 4127) // conditional expression is constant
51+
#endif
52+
4653
#if defined(__APPLE__)
4754
#include "TargetConditionals.h"
4855
#endif
@@ -1890,7 +1897,7 @@ class ConcurrentQueue
18901897
++pr_blockIndexSlotsUsed;
18911898
}
18921899

1893-
if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new ((T*)nullptr) T(std::forward<U>(element)))) {
1900+
MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new ((T*)nullptr) T(std::forward<U>(element)))) {
18941901
// The constructor may throw. We want the element not to appear in the queue in
18951902
// that case (without corrupting the queue):
18961903
MOODYCAMEL_TRY {
@@ -1916,7 +1923,7 @@ class ConcurrentQueue
19161923
blockIndex.load(std::memory_order_relaxed)->front.store(pr_blockIndexFront, std::memory_order_release);
19171924
pr_blockIndexFront = (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1);
19181925

1919-
if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new ((T*)nullptr) T(std::forward<U>(element)))) {
1926+
MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new ((T*)nullptr) T(std::forward<U>(element)))) {
19201927
this->tailIndex.store(newTailIndex, std::memory_order_release);
19211928
return true;
19221929
}
@@ -2132,7 +2139,7 @@ class ConcurrentQueue
21322139
block = block->next;
21332140
}
21342141

2135-
if (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new ((T*)nullptr) T(details::deref_noexcept(itemFirst)))) {
2142+
MOODYCAMEL_CONSTEXPR_IF (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new ((T*)nullptr) T(details::deref_noexcept(itemFirst)))) {
21362143
blockIndex.load(std::memory_order_relaxed)->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1), std::memory_order_release);
21372144
}
21382145
}
@@ -2147,11 +2154,11 @@ class ConcurrentQueue
21472154
this->tailBlock = firstAllocatedBlock;
21482155
}
21492156
while (true) {
2150-
auto stopIndex = (currentTailIndex & ~static_cast<index_t>(BLOCK_SIZE - 1)) + static_cast<index_t>(BLOCK_SIZE);
2157+
index_t stopIndex = (currentTailIndex & ~static_cast<index_t>(BLOCK_SIZE - 1)) + static_cast<index_t>(BLOCK_SIZE);
21512158
if (details::circular_less_than<index_t>(newTailIndex, stopIndex)) {
21522159
stopIndex = newTailIndex;
21532160
}
2154-
if (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new ((T*)nullptr) T(details::deref_noexcept(itemFirst)))) {
2161+
MOODYCAMEL_CONSTEXPR_IF (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new ((T*)nullptr) T(details::deref_noexcept(itemFirst)))) {
21552162
while (currentTailIndex != stopIndex) {
21562163
new ((*this->tailBlock)[currentTailIndex++]) T(*itemFirst++);
21572164
}
@@ -2213,8 +2220,9 @@ class ConcurrentQueue
22132220
this->tailBlock = this->tailBlock->next;
22142221
}
22152222

2216-
if (!MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new ((T*)nullptr) T(details::deref_noexcept(itemFirst))) && firstAllocatedBlock != nullptr) {
2217-
blockIndex.load(std::memory_order_relaxed)->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1), std::memory_order_release);
2223+
MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new ((T*)nullptr) T(details::deref_noexcept(itemFirst)))) {
2224+
if (firstAllocatedBlock != nullptr)
2225+
blockIndex.load(std::memory_order_relaxed)->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1), std::memory_order_release);
22182226
}
22192227

22202228
this->tailIndex.store(newTailIndex, std::memory_order_release);
@@ -2258,7 +2266,7 @@ class ConcurrentQueue
22582266
auto index = firstIndex;
22592267
do {
22602268
auto firstIndexInBlock = index;
2261-
auto endIndex = (index & ~static_cast<index_t>(BLOCK_SIZE - 1)) + static_cast<index_t>(BLOCK_SIZE);
2269+
index_t endIndex = (index & ~static_cast<index_t>(BLOCK_SIZE - 1)) + static_cast<index_t>(BLOCK_SIZE);
22622270
endIndex = details::circular_less_than<index_t>(firstIndex + static_cast<index_t>(actualCount), endIndex) ? firstIndex + static_cast<index_t>(actualCount) : endIndex;
22632271
auto block = localBlockIndex->entries[indexIndex].block;
22642272
if (MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, details::deref_noexcept(itemFirst) = std::move((*(*block)[index])))) {
@@ -2492,8 +2500,8 @@ class ConcurrentQueue
24922500
newBlock->owner = this;
24932501
#endif
24942502
newBlock->ConcurrentQueue::Block::template reset_empty<implicit_context>();
2495-
2496-
if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new ((T*)nullptr) T(std::forward<U>(element)))) {
2503+
2504+
MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new ((T*)nullptr) T(std::forward<U>(element)))) {
24972505
// May throw, try to insert now before we publish the fact that we have this new block
24982506
MOODYCAMEL_TRY {
24992507
new ((*newBlock)[currentTailIndex]) T(std::forward<U>(element));
@@ -2511,7 +2519,7 @@ class ConcurrentQueue
25112519

25122520
this->tailBlock = newBlock;
25132521

2514-
if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new ((T*)nullptr) T(std::forward<U>(element)))) {
2522+
MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new ((T*)nullptr) T(std::forward<U>(element)))) {
25152523
this->tailIndex.store(newTailIndex, std::memory_order_release);
25162524
return true;
25172525
}
@@ -2595,6 +2603,10 @@ class ConcurrentQueue
25952603
return false;
25962604
}
25972605

2606+
#ifdef _MSC_VER
2607+
#pragma warning(push)
2608+
#pragma warning(disable: 4706) // assignment within conditional expression
2609+
#endif
25982610
template<AllocationMode allocMode, typename It>
25992611
bool enqueue_bulk(It itemFirst, size_t count)
26002612
{
@@ -2630,6 +2642,7 @@ class ConcurrentQueue
26302642
auto head = this->headIndex.load(std::memory_order_relaxed);
26312643
assert(!details::circular_less_than<index_t>(currentTailIndex, head));
26322644
bool full = !details::circular_less_than<index_t>(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max<size_t>::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head));
2645+
26332646
if (full || !(indexInserted = insert_block_index_entry<allocMode>(idxEntry, currentTailIndex)) || (newBlock = this->parent->ConcurrentQueue::template requisition_block<allocMode>()) == nullptr) {
26342647
// Index allocation or block allocation failed; revert any other allocations
26352648
// and index insertions done so far for this operation
@@ -2680,11 +2693,11 @@ class ConcurrentQueue
26802693
this->tailBlock = firstAllocatedBlock;
26812694
}
26822695
while (true) {
2683-
auto stopIndex = (currentTailIndex & ~static_cast<index_t>(BLOCK_SIZE - 1)) + static_cast<index_t>(BLOCK_SIZE);
2696+
index_t stopIndex = (currentTailIndex & ~static_cast<index_t>(BLOCK_SIZE - 1)) + static_cast<index_t>(BLOCK_SIZE);
26842697
if (details::circular_less_than<index_t>(newTailIndex, stopIndex)) {
26852698
stopIndex = newTailIndex;
26862699
}
2687-
if (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new ((T*)nullptr) T(details::deref_noexcept(itemFirst)))) {
2700+
MOODYCAMEL_CONSTEXPR_IF (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new ((T*)nullptr) T(details::deref_noexcept(itemFirst)))) {
26882701
while (currentTailIndex != stopIndex) {
26892702
new ((*this->tailBlock)[currentTailIndex++]) T(*itemFirst++);
26902703
}
@@ -2744,6 +2757,9 @@ class ConcurrentQueue
27442757
this->tailIndex.store(newTailIndex, std::memory_order_release);
27452758
return true;
27462759
}
2760+
#ifdef _MSC_VER
2761+
#pragma warning(pop)
2762+
#endif
27472763

27482764
template<typename It>
27492765
size_t dequeue_bulk(It& itemFirst, size_t max)
@@ -2775,7 +2791,7 @@ class ConcurrentQueue
27752791
auto indexIndex = get_block_index_index_for_index(index, localBlockIndex);
27762792
do {
27772793
auto blockStartIndex = index;
2778-
auto endIndex = (index & ~static_cast<index_t>(BLOCK_SIZE - 1)) + static_cast<index_t>(BLOCK_SIZE);
2794+
index_t endIndex = (index & ~static_cast<index_t>(BLOCK_SIZE - 1)) + static_cast<index_t>(BLOCK_SIZE);
27792795
endIndex = details::circular_less_than<index_t>(firstIndex + static_cast<index_t>(actualCount), endIndex) ? firstIndex + static_cast<index_t>(actualCount) : endIndex;
27802796

27812797
auto entry = localBlockIndex->index[indexIndex];
@@ -2873,7 +2889,7 @@ class ConcurrentQueue
28732889
if (localBlockIndex == nullptr) {
28742890
return false; // this can happen if new_block_index failed in the constructor
28752891
}
2876-
auto newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) & (localBlockIndex->capacity - 1);
2892+
size_t newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) & (localBlockIndex->capacity - 1);
28772893
idxEntry = localBlockIndex->index[newTail];
28782894
if (idxEntry->key.load(std::memory_order_relaxed) == INVALID_BLOCK_BASE ||
28792895
idxEntry->value.load(std::memory_order_relaxed) == nullptr) {
@@ -3443,7 +3459,7 @@ class ConcurrentQueue
34433459
}
34443460

34453461
auto newHash = new (raw) ImplicitProducerHash;
3446-
newHash->capacity = newCapacity;
3462+
newHash->capacity = (size_t)newCapacity;
34473463
newHash->entries = reinterpret_cast<ImplicitProducerKVP*>(details::align_for<ImplicitProducerKVP>(raw + sizeof(ImplicitProducerHash)));
34483464
for (size_t i = 0; i != newCapacity; ++i) {
34493465
new (newHash->entries + i) ImplicitProducerKVP;
@@ -3557,23 +3573,26 @@ class ConcurrentQueue
35573573
template<typename TAlign>
35583574
static inline void* aligned_malloc(size_t size)
35593575
{
3560-
if (std::alignment_of<TAlign>::value <= std::alignment_of<details::max_align_t>::value)
3576+
MOODYCAMEL_CONSTEXPR_IF (std::alignment_of<TAlign>::value <= std::alignment_of<details::max_align_t>::value)
35613577
return (Traits::malloc)(size);
3562-
size_t alignment = std::alignment_of<TAlign>::value;
3563-
void* raw = (Traits::malloc)(size + alignment - 1 + sizeof(void*));
3564-
if (!raw)
3565-
return nullptr;
3566-
char* ptr = details::align_for<TAlign>(reinterpret_cast<char*>(raw) + sizeof(void*));
3567-
*(reinterpret_cast<void**>(ptr) - 1) = raw;
3568-
return ptr;
3578+
else {
3579+
size_t alignment = std::alignment_of<TAlign>::value;
3580+
void* raw = (Traits::malloc)(size + alignment - 1 + sizeof(void*));
3581+
if (!raw)
3582+
return nullptr;
3583+
char* ptr = details::align_for<TAlign>(reinterpret_cast<char*>(raw) + sizeof(void*));
3584+
*(reinterpret_cast<void**>(ptr) - 1) = raw;
3585+
return ptr;
3586+
}
35693587
}
35703588

35713589
template<typename TAlign>
35723590
static inline void aligned_free(void* ptr)
35733591
{
3574-
if (std::alignment_of<TAlign>::value <= std::alignment_of<details::max_align_t>::value)
3592+
MOODYCAMEL_CONSTEXPR_IF (std::alignment_of<TAlign>::value <= std::alignment_of<details::max_align_t>::value)
35753593
return (Traits::free)(ptr);
3576-
(Traits::free)(ptr ? *(reinterpret_cast<void**>(ptr) - 1) : nullptr);
3594+
else
3595+
(Traits::free)(ptr ? *(reinterpret_cast<void**>(ptr) - 1) : nullptr);
35773596
}
35783597

35793598
template<typename U>
@@ -3679,15 +3698,15 @@ ConsumerToken::ConsumerToken(ConcurrentQueue<T, Traits>& queue)
36793698
: itemsConsumedFromCurrent(0), currentProducer(nullptr), desiredProducer(nullptr)
36803699
{
36813700
initialOffset = queue.nextExplicitConsumerId.fetch_add(1, std::memory_order_release);
3682-
lastKnownGlobalOffset = -1;
3701+
lastKnownGlobalOffset = (std::uint32_t)-1;
36833702
}
36843703

36853704
template<typename T, typename Traits>
36863705
ConsumerToken::ConsumerToken(BlockingConcurrentQueue<T, Traits>& queue)
36873706
: itemsConsumedFromCurrent(0), currentProducer(nullptr), desiredProducer(nullptr)
36883707
{
36893708
initialOffset = reinterpret_cast<ConcurrentQueue<T, Traits>*>(&queue)->nextExplicitConsumerId.fetch_add(1, std::memory_order_release);
3690-
lastKnownGlobalOffset = -1;
3709+
lastKnownGlobalOffset = (std::uint32_t)-1;
36913710
}
36923711

36933712
template<typename T, typename Traits>
@@ -3714,6 +3733,10 @@ inline void swap(typename ConcurrentQueue<T, Traits>::ImplicitProducerKVP& a, ty
37143733

37153734
}
37163735

3736+
#if defined(_MSC_VER) && (!defined(_HAS_CXX17) || !_HAS_CXX17)
3737+
#pragma warning(pop)
3738+
#endif
3739+
37173740
#if defined(__GNUC__)
37183741
#pragma GCC diagnostic pop
37193742
#endif

tests/corealgos.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ struct ThreadLocal
277277
auto raw = static_cast<char*>(corealgos_allocator::malloc(sizeof(InnerHash) + std::alignment_of<KeyValuePair>::value - 1 + sizeof(KeyValuePair) * newCapacity));
278278
if (raw == nullptr) {
279279
// Allocation failed
280-
currentHashCount.fetch_add(-1, std::memory_order_relaxed);
280+
currentHashCount.fetch_add((uint32_t)-1, std::memory_order_relaxed);
281281
resizeInProgress.clear(std::memory_order_relaxed);
282282
return nullptr;
283283
}
@@ -434,15 +434,15 @@ struct FreeList
434434
assert((head->freeListRefs.load(std::memory_order_relaxed) & SHOULD_BE_ON_FREELIST) == 0);
435435

436436
// Decrease refcount twice, once for our ref, and once for the list's ref
437-
head->freeListRefs.fetch_add(-2, std::memory_order_release);
437+
head->freeListRefs.fetch_add(-2u, std::memory_order_release);
438438
return head;
439439
}
440440

441441
// OK, the head must have changed on us, but we still need to decrease the refcount we
442442
// increased.
443443
// Note that we don't need to release any memory effects, but we do need to ensure that the reference
444444
// count decrement happens-after the CAS on the head.
445-
refs = prevHead->freeListRefs.fetch_add(-1, std::memory_order_acq_rel);
445+
refs = prevHead->freeListRefs.fetch_add(-1u, std::memory_order_acq_rel);
446446
if (refs == SHOULD_BE_ON_FREELIST + 1) {
447447
add_knowing_refcount_is_zero(prevHead);
448448
}

tests/fuzztests/fuzztests.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ bool run_test(uint64_t seed, int iterations, test_type& out_type, const char*& o
484484
count = q.try_dequeue_bulk(bulkData.begin(), bulkData.size());
485485
}
486486
for (std::size_t k = 0; k != count; ++k) {
487-
auto item = bulkData[k];
487+
item = bulkData[k];
488488
ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) >= 0 && (item & 0xFFFFFF) < (int)largestOpCount);
489489
ASSERT_OR_FAIL_THREAD((item & 0xFFFFFF) > lastItems[item >> 24]);
490490
lastItems[item >> 24] = item & 0xFFFFFF;
@@ -784,12 +784,12 @@ int main(int argc, char** argv)
784784
}
785785
}
786786

787-
int result = 0;
787+
int exitCode = 0;
788788
test_type test;
789789
const char* failReason;
790790
if (singleSeed) {
791791
if (!run_test(seed, SINGLE_SEED_ITERATIONS, test, failReason)) {
792-
result = 1;
792+
exitCode = 1;
793793
std::ofstream fout(LOG_FILE, std::ios::app);
794794
fout << test_names[test] << " failed: " << failReason << std::endl;
795795
std::printf(" %s failed: %s\n", test_names[test], failReason);
@@ -818,7 +818,7 @@ int main(int argc, char** argv)
818818
std::signal(SIGSEGV, signal_handler);
819819
std::signal(SIGABRT, signal_handler);
820820

821-
int result;
821+
bool result;
822822
try {
823823
result = run_test(seed, 2, test, failReason);
824824
}
@@ -839,7 +839,7 @@ int main(int argc, char** argv)
839839
std::signal(SIGABRT, SIG_DFL);
840840

841841
if (!result) {
842-
result = 1;
842+
exitCode = 1;
843843
std::ofstream fout(LOG_FILE, std::ios::app);
844844
fout << "*** Failure detected!\n Seed: " << std::hex << seed << "\n Test: " << test_names[test] << "\n Reason: " << failReason << std::endl;
845845
std::printf("*** Failure detected!\n Seed: %08x%08x\n Test: %s\n Reason: %s\n", (uint32_t)(seed >> 32), (uint32_t)(seed), test_names[test], failReason);
@@ -863,5 +863,5 @@ int main(int argc, char** argv)
863863
}
864864
}
865865

866-
return result;
866+
return exitCode;
867867
}

0 commit comments

Comments
 (0)