From 98c383e7e7b7f7e0bc9964e3d18f9aaa3539ff59 Mon Sep 17 00:00:00 2001 From: Mark Benvenuto Date: Fri, 20 Oct 2017 17:11:32 -0400 Subject: [PATCH] SERVER-17414 Enable Warnings As Errors on Windows, and disable/fix warnings --- SConstruct | 4 ++ src/mongo/base/parse_number.cpp | 5 ++ src/mongo/bson/util/builder_test.cpp | 3 +- src/mongo/db/fts/unicode/string_test.cpp | 54 ++++++++++--------- src/mongo/db/geo/hash.cpp | 4 ++ src/mongo/db/storage/kv/kv_catalog.cpp | 2 +- .../mmap_v1/record_access_tracker_test.cpp | 4 ++ src/mongo/dbtests/documentsourcetests.cpp | 4 +- src/mongo/platform/decimal128.cpp | 9 +++- src/mongo/util/exception_filter_win32.cpp | 7 ++- src/mongo/util/net/sock.h | 2 +- src/mongo/util/processinfo_windows.cpp | 5 ++ src/mongo/util/represent_as_test.cpp | 9 ++-- src/mongo/util/stacktrace_windows.cpp | 7 ++- src/mongo/util/summation_test.cpp | 5 ++ src/mongo/util/time_support_test.cpp | 6 +++ .../boost/format/alt_sstream_impl.hpp | 2 +- 17 files changed, 92 insertions(+), 40 deletions(-) diff --git a/SConstruct b/SConstruct index 22cc72559f763..8228a1030362d 100644 --- a/SConstruct +++ b/SConstruct @@ -1502,6 +1502,10 @@ elif env.TargetOSIs('windows'): # object called lock on the stack. env.Append( CCFLAGS=["/we4013", "/we4099", "/we4930"] ) + # Warnings as errors + if not has_option("disable-warnings-as-errors"): + env.Append( CCFLAGS=["/WX"] ) + env.Append( CPPDEFINES=["_CONSOLE","_CRT_SECURE_NO_WARNINGS", "_SCL_SECURE_NO_WARNINGS"] ) # this would be for pre-compiled headers, could play with it later diff --git a/src/mongo/base/parse_number.cpp b/src/mongo/base/parse_number.cpp index e9d4b6a73ee0a..c7f7258ac5c79 100644 --- a/src/mongo/base/parse_number.cpp +++ b/src/mongo/base/parse_number.cpp @@ -173,7 +173,12 @@ Status parseNumberFromStringWithBase(StringData wholeString, int base, NumberTyp if (magnitude > maxMagnitude) return Status(ErrorCodes::FailedToParse, "Overflow"); +#pragma warning(push) +// C4146: unary minus operator applied to unsigned type, result still unsigned +#pragma warning(disable : 4146) *result = NumberType(isNegative ? -magnitude : magnitude); +#pragma warning(pop) + return Status::OK(); } diff --git a/src/mongo/bson/util/builder_test.cpp b/src/mongo/bson/util/builder_test.cpp index b45a0dcf5aab0..75e0235bf7ddc 100644 --- a/src/mongo/bson/util/builder_test.cpp +++ b/src/mongo/bson/util/builder_test.cpp @@ -46,7 +46,8 @@ TEST(Builder, String1) { TEST(Builder, StringBuilderAddress) { const void* longPtr = reinterpret_cast(-1); - const void* shortPtr = reinterpret_cast(0xDEADBEEF); + const void* shortPtr = reinterpret_cast(static_cast(0xDEADBEEF)); + const void* nullPtr = NULL; StringBuilder sb; diff --git a/src/mongo/db/fts/unicode/string_test.cpp b/src/mongo/db/fts/unicode/string_test.cpp index e67228f76de1f..c73752b6a12d3 100644 --- a/src/mongo/db/fts/unicode/string_test.cpp +++ b/src/mongo/db/fts/unicode/string_test.cpp @@ -42,6 +42,10 @@ #define UTF8(x) x #endif +// Convert integer literals that are > 127 to unsigned char before converting to char +// to avoid MSVC C4309: truncation of constant value +#define C(x) static_cast(static_cast(x)) + namespace mongo { namespace unicode { @@ -92,7 +96,7 @@ TEST(UnicodeString, RemoveDiacritics) { const char test1[] = UTF8("¿CUÁNTOS AÑOS TIENES TÚ?"); // NFD Normalized Text ("Café"). - const char test2[] = {'C', 'a', 'f', 'e', static_cast(0xcc), static_cast(0x81), 0}; + const char test2[] = {'C', 'a', 'f', 'e', C(0xcc), C(0x81), 0}; TEST_CASE_FOLD_AND_STRIP_DIACRITICS( UTF8("¿CUANTOS ANOS TIENES TU?"), test1, kCaseSensitive, kNormal); @@ -146,7 +150,7 @@ TEST(UnicodeString, CaseFoldingAndRemoveDiacritics) { const char test2[] = UTF8("¿CUÁNTOS AÑOS TIENES TÚ?"); // NFD Normalized Text ("CAFÉ"). - const char test3[] = {'C', 'A', 'F', 'E', static_cast(0xcc), static_cast(0x81), 0}; + const char test3[] = {'C', 'A', 'F', 'E', C(0xCc), C(0x81), 0}; TEST_CASE_FOLD_AND_STRIP_DIACRITICS(UTF8("ποσο χρονων εισαι?"), test1, 0, kNormal); TEST_CASE_FOLD_AND_STRIP_DIACRITICS(UTF8("¿cuantos anos tienes tu?"), test2, 0, kNormal); @@ -192,25 +196,23 @@ TEST(UnicodeString, SubstringMatchTurkish) { TEST(UnicodeString, BadUTF8) { // Overlong. - const char invalid1[] = {static_cast(0xC0), static_cast(0xAF), 0}; + const char invalid1[] = {C(0xC0), C(0xAF), 0}; // Invalid code positions. - const char invalid2[] = { - static_cast(0xED), static_cast(0xA0), static_cast(0x80), 0}; - const char invalid3[] = { - static_cast(0xC2), static_cast(0x41), static_cast(0x42), 0}; + const char invalid2[] = {C(0xED), C(0xA0), C(0x80), 0}; + const char invalid3[] = {C(0xC2), static_cast(0x41), static_cast(0x42), 0}; const char invalid4[] = {static_cast(0x61), - static_cast(0xF1), - static_cast(0x80), - static_cast(0x80), - static_cast(0xE1), - static_cast(0x80), - static_cast(0xC2), + C(0xF1), + C(0x80), + C(0x80), + C(0xE1), + C(0x80), + C(0xC2), static_cast(0x62), - static_cast(0x80), + C(0x80), static_cast(0x63), - static_cast(0x80), - static_cast(0xBF), + C(0x80), + C(0xBF), static_cast(0x64), 0}; @@ -240,16 +242,16 @@ TEST(UnicodeString, UTF32ToUTF8) { original.push_back(0); std::string expected_result; - expected_result.push_back(0x4D); - expected_result.push_back(0xD0); - expected_result.push_back(0xB0); - expected_result.push_back(0xE4); - expected_result.push_back(0xBA); - expected_result.push_back(0x8C); - expected_result.push_back(0xF0); - expected_result.push_back(0x90); - expected_result.push_back(0x8C); - expected_result.push_back(0x82); + expected_result.push_back(C(0x4D)); + expected_result.push_back(C(0xD0)); + expected_result.push_back(C(0xB0)); + expected_result.push_back(C(0xE4)); + expected_result.push_back(C(0xBA)); + expected_result.push_back(C(0x8C)); + expected_result.push_back(C(0xF0)); + expected_result.push_back(C(0x90)); + expected_result.push_back(C(0x8C)); + expected_result.push_back(C(0x82)); expected_result.push_back(0); std::string result(11, '\0'); diff --git a/src/mongo/db/geo/hash.cpp b/src/mongo/db/geo/hash.cpp index affc42e7fba22..b00a637be4378 100644 --- a/src/mongo/db/geo/hash.cpp +++ b/src/mongo/db/geo/hash.cpp @@ -847,7 +847,11 @@ double GeoHashConverter::sizeOfDiag(const GeoHash& a) const { double GeoHashConverter::sizeEdge(unsigned level) const { invariant(level >= 0); invariant((int)level <= _params.bits); +#pragma warning(push) +// C4146: unary minus operator applied to unsigned type, result still unsigned +#pragma warning(disable : 4146) return ldexp(_params.max - _params.min, -level); +#pragma warning(pop) } // Convert from a double in [0, (max-min)*scaling] to [min, max] diff --git a/src/mongo/db/storage/kv/kv_catalog.cpp b/src/mongo/db/storage/kv/kv_catalog.cpp index f92e1784294fa..b93b66178da33 100644 --- a/src/mongo/db/storage/kv/kv_catalog.cpp +++ b/src/mongo/db/storage/kv/kv_catalog.cpp @@ -70,7 +70,7 @@ void appendPositionsOfBitsSet(uint64_t value, StringBuilder* sb) { *sb << ", "; } *sb << lowestSetBitPosition; - value ^= (1 << lowestSetBitPosition); + value ^= (1ULL << lowestSetBitPosition); firstIteration = false; } *sb << " ]"; diff --git a/src/mongo/db/storage/mmap_v1/record_access_tracker_test.cpp b/src/mongo/db/storage/mmap_v1/record_access_tracker_test.cpp index 94933c7f9b752..7b5c13a1029ad 100644 --- a/src/mongo/db/storage/mmap_v1/record_access_tracker_test.cpp +++ b/src/mongo/db/storage/mmap_v1/record_access_tracker_test.cpp @@ -40,7 +40,11 @@ namespace { const std::unique_ptr clock = stdx::make_unique(); const void* pointerOf(int data) { +#pragma warning(push) +// C4312: 'reinterpret_cast': conversion from 'int' to 'const void *' of greater size +#pragma warning(disable : 4312) return reinterpret_cast(data); +#pragma warning(pop) } TEST(RecordAccessTrackerTest, TouchRecordTwice) { diff --git a/src/mongo/dbtests/documentsourcetests.cpp b/src/mongo/dbtests/documentsourcetests.cpp index ab3ed2b08a0b2..69f03245f3731 100644 --- a/src/mongo/dbtests/documentsourcetests.cpp +++ b/src/mongo/dbtests/documentsourcetests.cpp @@ -314,7 +314,7 @@ TEST_F(DocumentSourceCursorTest, SerializationRespectsExplainModes) { TEST_F(DocumentSourceCursorTest, TailableAwaitDataCursorStillUsableAfterTimeout) { // Make sure the collection exists, otherwise we'll default to a NO_YIELD yield policy. const bool capped = true; - const bool cappedSize = 1024; + const long long cappedSize = 1024; ASSERT_TRUE(client.createCollection(nss.ns(), cappedSize, capped)); client.insert(nss.ns(), BSON("a" << 1)); @@ -392,7 +392,7 @@ TEST_F(DocumentSourceCursorTest, NonAwaitDataCursorShouldErrorAfterTimeout) { TEST_F(DocumentSourceCursorTest, TailableAwaitDataCursorShouldErrorAfterBeingKilled) { // Make sure the collection exists, otherwise we'll default to a NO_YIELD yield policy. const bool capped = true; - const bool cappedSize = 1024; + const long long cappedSize = 1024; ASSERT_TRUE(client.createCollection(nss.ns(), cappedSize, capped)); client.insert(nss.ns(), BSON("a" << 1)); diff --git a/src/mongo/platform/decimal128.cpp b/src/mongo/platform/decimal128.cpp index 6d48fa18d1913..a98036fb84714 100644 --- a/src/mongo/platform/decimal128.cpp +++ b/src/mongo/platform/decimal128.cpp @@ -776,8 +776,13 @@ namespace { // Get the representation of 1 with 17 zeros (half of decimal128's 34 digit precision) const std::uint64_t t17 = 100ull * 1000 * 1000 * 1000 * 1000 * 1000; // Get the low 64 bits of 34 consecutive decimal 9's -// t17 * 17 gives 1 with 34 0's, so subtract 1 to get all 9's -const std::uint64_t t34lo64 = t17 * t17 - 1; +// t17 * 17 gives 1 with 34 0's, so subtract 1 to get all 9's == 4003012203950112767 +// Using the computed constant avoids a MSVC warning. +// Computed by running the calculations in Python, and verified with static_assert. +const std::uint64_t t34lo64 = 4003012203950112767ULL; +#if defined(__GNUC__) +static_assert(t34lo64 == t17 * t17 - 1, "precomputed constant is wrong"); +#endif // Mod t17 by 2^32 to get the low 32 bits of t17's binary representation const std::uint64_t t17lo32 = t17 % (1ull << 32); // Divide t17 by 2^32 to get the high 32 bits of t17's binary representation diff --git a/src/mongo/util/exception_filter_win32.cpp b/src/mongo/util/exception_filter_win32.cpp index db0e3e9bb5665..32dffed8d853e 100644 --- a/src/mongo/util/exception_filter_win32.cpp +++ b/src/mongo/util/exception_filter_win32.cpp @@ -32,7 +32,12 @@ #include "mongo/platform/basic.h" +#pragma warning(push) +// C4091: 'typedef ': ignored on left of '' when no variable is declared +#pragma warning(disable : 4091) #include +#pragma warning(pop) + #include #include "mongo/config.h" @@ -150,7 +155,7 @@ LONG WINAPI exceptionFilter(struct _EXCEPTION_POINTERS* excPointers) { } sprintf_s(addressString, sizeof(addressString), - " 0x%p", + " 0x%llx", excPointers->ExceptionRecord->ExceptionInformation[1]); log() << "*** access violation was a " << acTypeString << addressString; } diff --git a/src/mongo/util/net/sock.h b/src/mongo/util/net/sock.h index c01c9bf3a18a5..42d69757c60d0 100644 --- a/src/mongo/util/net/sock.h +++ b/src/mongo/util/net/sock.h @@ -250,7 +250,7 @@ class Socket { /** raw recv, same semantics as ::recv */ int _recv(char* buf, int max); - int _fd; + SOCKET _fd; uint64_t _fdCreationMicroSec; SockAddr _local; SockAddr _remote; diff --git a/src/mongo/util/processinfo_windows.cpp b/src/mongo/util/processinfo_windows.cpp index 7686a9d2ebe94..a683d85854734 100644 --- a/src/mongo/util/processinfo_windows.cpp +++ b/src/mongo/util/processinfo_windows.cpp @@ -291,7 +291,12 @@ void ProcessInfo::SystemInfo::collectSystemInfo() { // get OS version info ZeroMemory(&osvi, sizeof(osvi)); osvi.dwOSVersionInfoSize = sizeof(osvi); +#pragma warning(push) +// GetVersionEx is deprecated +#pragma warning(disable : 4996) if (GetVersionEx((OSVERSIONINFO*)&osvi)) { +#pragma warning(pop) + verstr << osvi.dwMajorVersion << "." << osvi.dwMinorVersion; if (osvi.wServicePackMajor) verstr << " SP" << osvi.wServicePackMajor; diff --git a/src/mongo/util/represent_as_test.cpp b/src/mongo/util/represent_as_test.cpp index c565c712ba695..e1476be0210ac 100644 --- a/src/mongo/util/represent_as_test.cpp +++ b/src/mongo/util/represent_as_test.cpp @@ -71,7 +71,7 @@ const double kInt32MinAsDouble = kInt32Min; const uint32_t kUInt32Zero = 0; const uint32_t kUInt32Max = std::numeric_limits::max(); const int64_t kUInt32MaxAsInt64 = kUInt32Max; -const float kUInt32MaxAsFloat = kUInt32Max; +const float kUInt32MaxAsFloat = static_cast(kUInt32Max); const double kUInt32MaxAsDouble = kUInt32Max; // 64-bit integer values @@ -79,14 +79,15 @@ const int64_t kInt64Zero = 0; const int64_t kInt64Max = std::numeric_limits::max(); const int64_t kInt64Min = std::numeric_limits::lowest(); const uint64_t kInt64MaxAsUInt64 = kInt64Max; -const double kInt64MaxAsDouble = kInt64Max; +const double kInt64MaxAsDouble = static_cast(kInt64Max); const double kInt64MinAsDouble = kInt64Min; // Unsigned 64-bit integer values const uint64_t kUInt64Zero = 0; const uint64_t kUInt64Max = std::numeric_limits::max(); -const float kUInt64MaxAsFloat = kUInt64Max; -const double kUInt64MaxAsDouble = kUInt64Max; +const float kUInt64MaxAsFloat = static_cast(kUInt64Max); +const double kUInt64MaxAsDouble = static_cast(kUInt64Max); + // Long long values const long long kLongLongMax = std::numeric_limits::max(); diff --git a/src/mongo/util/stacktrace_windows.cpp b/src/mongo/util/stacktrace_windows.cpp index ae0ed8a0997c9..a2a2ea2916216 100644 --- a/src/mongo/util/stacktrace_windows.cpp +++ b/src/mongo/util/stacktrace_windows.cpp @@ -31,7 +31,12 @@ #include "mongo/util/stacktrace.h" +#pragma warning(push) +// C4091: 'typedef ': ignored on left of '' when no variable is declared +#pragma warning(disable : 4091) #include +#pragma warning(pop) + #include #include #include @@ -213,7 +218,7 @@ static void getsymbolAndOffset(HANDLE process, std::string symbolString(symbolInfo->Name); static const size_t bufferSize = 32; std::unique_ptr symbolOffset(new char[bufferSize]); - _snprintf(symbolOffset.get(), bufferSize, "+0x%x", displacement64); + _snprintf(symbolOffset.get(), bufferSize, "+0x%llux", displacement64); symbolString += symbolOffset.get(); returnedSymbolAndOffset->swap(symbolString); } diff --git a/src/mongo/util/summation_test.cpp b/src/mongo/util/summation_test.cpp index 6e86690e1714a..8be8cbceb7ca8 100644 --- a/src/mongo/util/summation_test.cpp +++ b/src/mongo/util/summation_test.cpp @@ -67,7 +67,12 @@ std::vector longValues = { 1LL << 52, 1LL << 53, limits::max() / 2, + +#pragma warning(push) +// C4308: negative integral constant converted to unsigned type +#pragma warning(disable : 4308) static_cast(1ULL << 63) - (1ULL << (63 - 53 - 1)), // Halfway between two doubles +#pragma warning(pop) limits::max() - 1, limits::max()}; diff --git a/src/mongo/util/time_support_test.cpp b/src/mongo/util/time_support_test.cpp index 0d7f6b875b996..dc48d01e58ad0 100644 --- a/src/mongo/util/time_support_test.cpp +++ b/src/mongo/util/time_support_test.cpp @@ -50,6 +50,11 @@ char tzEnvString[] = "TZ=EST+5EDT"; #else char tzEnvString[] = "TZ=America/New_York"; #endif + +#pragma warning(push) +// C4996: The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant +// name: _putenv. See online help for details. +#pragma warning(disable : 4996) MONGO_INITIALIZER(SetTimeZoneToEasternForTest)(InitializerContext*) { if (-1 == putenv(tzEnvString)) { return Status(ErrorCodes::BadValue, errnoWithDescription()); @@ -57,6 +62,7 @@ MONGO_INITIALIZER(SetTimeZoneToEasternForTest)(InitializerContext*) { tzset(); return Status::OK(); } +#pragma warning(pop) TEST(TimeFormatting, DateAsISO8601UTCString) { ASSERT_EQUALS(std::string("1970-01-01T00:00:00.000Z"), dateToISOStringUTC(Date_t())); diff --git a/src/third_party/boost-1.60.0/boost/format/alt_sstream_impl.hpp b/src/third_party/boost-1.60.0/boost/format/alt_sstream_impl.hpp index 9975e4f96b0a3..8eb5ad8f38fd2 100644 --- a/src/third_party/boost-1.60.0/boost/format/alt_sstream_impl.hpp +++ b/src/third_party/boost-1.60.0/boost/format/alt_sstream_impl.hpp @@ -173,7 +173,7 @@ namespace boost { return (pos_type(off)); } else { - BOOST_ASSERT(0); // 27.4.3.2 allows undefined-behaviour here + BOOST_ASSERT(0); // 27.4.3.2 allows undefined-behaviour here return pos_type(off_type(-1)); } }