From 3cc77d5d635c2411f327cc4f262f37abb66ff43c Mon Sep 17 00:00:00 2001 From: Zhihao Yuan Date: Wed, 18 Jan 2017 16:16:07 -0600 Subject: [PATCH] Treat signed-unsigned conversions as errors. --- CMakeLists.txt | 2 ++ example/CMakeLists.txt | 5 ++--- include/rapidjson/encodedstream.h | 2 +- include/rapidjson/encodings.h | 6 +++--- include/rapidjson/internal/dtoa.h | 8 ++++---- include/rapidjson/internal/ieee754.h | 4 ++-- include/rapidjson/internal/regex.h | 4 ++-- include/rapidjson/internal/strtod.h | 14 +++++++------- include/rapidjson/istreamwrapper.h | 2 +- include/rapidjson/pointer.h | 6 +++--- include/rapidjson/schema.h | 2 +- include/rapidjson/writer.h | 2 +- test/perftest/CMakeLists.txt | 2 ++ test/unittest/CMakeLists.txt | 7 +++---- test/unittest/encodingstest.cpp | 2 +- test/unittest/itoatest.cpp | 4 ++-- 16 files changed, 37 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ccda4b..9257926 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native") endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror") + set(EXTRA_CXX_FLAGS -Weffc++ -Wswitch-default -Wfloat-equal -Wconversion -Wsign-conversion) if (RAPIDJSON_BUILD_CXX11) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7.0") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") @@ -86,6 +87,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native") endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-missing-field-initializers") + set(EXTRA_CXX_FLAGS -Weffc++ -Wswitch-default -Wfloat-equal -Wconversion -Wimplicit-fallthrough -Weverything) if (RAPIDJSON_BUILD_CXX11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") endif() diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 4d448cc..bec6a8c 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -24,11 +24,10 @@ set(EXAMPLES include_directories("../include/") add_definitions(-D__STDC_FORMAT_MACROS) +set_property(DIRECTORY PROPERTY COMPILE_OPTIONS ${EXTRA_CXX_FLAGS}) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -Werror -Wall -Wextra -Weffc++ -Wswitch-default") -elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough -Weverything") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") endif() foreach (example ${EXAMPLES}) diff --git a/include/rapidjson/encodedstream.h b/include/rapidjson/encodedstream.h index 1450683..223601c 100644 --- a/include/rapidjson/encodedstream.h +++ b/include/rapidjson/encodedstream.h @@ -200,7 +200,7 @@ private: // xx xx xx xx UTF-8 if (!hasBOM_) { - unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); + int pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); switch (pattern) { case 0x08: type_ = kUTF32BE; break; case 0x0A: type_ = kUTF16BE; break; diff --git a/include/rapidjson/encodings.h b/include/rapidjson/encodings.h index baa7c2b..ed7d44d 100644 --- a/include/rapidjson/encodings.h +++ b/include/rapidjson/encodings.h @@ -157,7 +157,7 @@ struct UTF8 { if (type >= 32) { *codepoint = 0; } else { - *codepoint = (0xFF >> type) & static_cast(c); + *codepoint = (0xFFu >> type) & static_cast(c); } bool result = true; switch (type) { @@ -283,7 +283,7 @@ struct UTF16 { RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); unsigned v = codepoint - 0x10000; os.Put(static_cast((v >> 10) | 0xD800)); - os.Put((v & 0x3FF) | 0xDC00); + os.Put(static_cast((v & 0x3FF) | 0xDC00)); } } @@ -299,7 +299,7 @@ struct UTF16 { RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); unsigned v = codepoint - 0x10000; PutUnsafe(os, static_cast((v >> 10) | 0xD800)); - PutUnsafe(os, (v & 0x3FF) | 0xDC00); + PutUnsafe(os, static_cast((v & 0x3FF) | 0xDC00)); } } diff --git a/include/rapidjson/internal/dtoa.h b/include/rapidjson/internal/dtoa.h index 8d6350e..bf2e9b2 100644 --- a/include/rapidjson/internal/dtoa.h +++ b/include/rapidjson/internal/dtoa.h @@ -41,7 +41,7 @@ inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uin } } -inline unsigned CountDecimalDigit32(uint32_t n) { +inline int CountDecimalDigit32(uint32_t n) { // Simple pure C++ implementation was faster than __builtin_clz version in this situation. if (n < 10) return 1; if (n < 100) return 2; @@ -63,7 +63,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff const DiyFp wp_w = Mp - W; uint32_t p1 = static_cast(Mp.f >> -one.e); uint64_t p2 = Mp.f & (one.f - 1); - unsigned kappa = CountDecimalDigit32(p1); // kappa in [0, 9] + int kappa = CountDecimalDigit32(p1); // kappa in [0, 9] *len = 0; while (kappa > 0) { @@ -102,8 +102,8 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff kappa--; if (p2 < delta) { *K += kappa; - int index = -static_cast(kappa); - GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[-static_cast(kappa)] : 0)); + int index = -kappa; + GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[index] : 0)); return; } } diff --git a/include/rapidjson/internal/ieee754.h b/include/rapidjson/internal/ieee754.h index 82bb0b9..c2684ba 100644 --- a/include/rapidjson/internal/ieee754.h +++ b/include/rapidjson/internal/ieee754.h @@ -48,13 +48,13 @@ public: int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } - static unsigned EffectiveSignificandSize(int order) { + static int EffectiveSignificandSize(int order) { if (order >= -1021) return 53; else if (order <= -1074) return 0; else - return static_cast(order) + 1074; + return order + 1074; } private: diff --git a/include/rapidjson/internal/regex.h b/include/rapidjson/internal/regex.h index 936b714..1369ea2 100644 --- a/include/rapidjson/internal/regex.h +++ b/include/rapidjson/internal/regex.h @@ -688,8 +688,8 @@ private: bool matched = AddState(l, s.out); return AddState(l, s.out1) || matched; } - else if (!(stateSet_[index >> 5] & (1 << (index & 31)))) { - stateSet_[index >> 5] |= (1 << (index & 31)); + else if (!(stateSet_[index >> 5] & (1u << (index & 31)))) { + stateSet_[index >> 5] |= (1u << (index & 31)); *l.template PushUnsafe() = index; } return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation. diff --git a/include/rapidjson/internal/strtod.h b/include/rapidjson/internal/strtod.h index 289c413..adf49e3 100644 --- a/include/rapidjson/internal/strtod.h +++ b/include/rapidjson/internal/strtod.h @@ -140,8 +140,8 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit significand++; size_t remaining = length - i; - const unsigned kUlpShift = 3; - const unsigned kUlp = 1 << kUlpShift; + const int kUlpShift = 3; + const int kUlp = 1 << kUlpShift; int64_t error = (remaining == 0) ? 0 : kUlp / 2; DiyFp v(significand, 0); @@ -177,17 +177,17 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit v = v.Normalize(); error <<= oldExp - v.e; - const unsigned effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); - unsigned precisionSize = 64 - effectiveSignificandSize; + const int effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); + int precisionSize = 64 - effectiveSignificandSize; if (precisionSize + kUlpShift >= 64) { - unsigned scaleExp = (precisionSize + kUlpShift) - 63; + int scaleExp = (precisionSize + kUlpShift) - 63; v.f >>= scaleExp; v.e += scaleExp; - error = (error >> scaleExp) + 1 + static_cast(kUlp); + error = (error >> scaleExp) + 1 + kUlp; precisionSize -= scaleExp; } - DiyFp rounded(v.f >> precisionSize, v.e + static_cast(precisionSize)); + DiyFp rounded(v.f >> precisionSize, v.e + precisionSize); const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; if (precisionBits >= halfWay + static_cast(error)) { diff --git a/include/rapidjson/istreamwrapper.h b/include/rapidjson/istreamwrapper.h index f5fe289..8639c8c 100644 --- a/include/rapidjson/istreamwrapper.h +++ b/include/rapidjson/istreamwrapper.h @@ -54,7 +54,7 @@ public: Ch Peek() const { typename StreamType::int_type c = stream_.peek(); - return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast(c) : '\0'; + return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast(c) : static_cast('\0'); } Ch Take() { diff --git a/include/rapidjson/pointer.h b/include/rapidjson/pointer.h index 4d6391f..bc7acfd 100644 --- a/include/rapidjson/pointer.h +++ b/include/rapidjson/pointer.h @@ -274,7 +274,7 @@ public: else { Ch name[21]; for (size_t i = 0; i <= length; i++) - name[i] = buffer[i]; + name[i] = static_cast(buffer[i]); Token token = { name, length, index }; return Append(token, allocator); } @@ -1029,8 +1029,8 @@ private: unsigned char u = static_cast(c); static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; os_.Put('%'); - os_.Put(hexDigits[u >> 4]); - os_.Put(hexDigits[u & 15]); + os_.Put(static_cast(hexDigits[u >> 4])); + os_.Put(static_cast(hexDigits[u & 15])); } private: OutputStream& os_; diff --git a/include/rapidjson/schema.h b/include/rapidjson/schema.h index 4760d1b..3f81d9b 100644 --- a/include/rapidjson/schema.h +++ b/include/rapidjson/schema.h @@ -1263,7 +1263,7 @@ struct TokenHelper { char buffer[21]; size_t length = static_cast((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer); for (size_t i = 0; i < length; i++) - *documentStack.template Push() = buffer[i]; + *documentStack.template Push() = static_cast(buffer[i]); } }; diff --git a/include/rapidjson/writer.h b/include/rapidjson/writer.h index 8f6e174..874c555 100644 --- a/include/rapidjson/writer.h +++ b/include/rapidjson/writer.h @@ -352,7 +352,7 @@ protected: char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); PutReserve(*os_, static_cast(end - buffer)); for (char* p = buffer; p != end; ++p) - PutUnsafe(*os_, static_cast(*p)); + PutUnsafe(*os_, static_cast(*p)); return true; } diff --git a/test/perftest/CMakeLists.txt b/test/perftest/CMakeLists.txt index c33aae4..035e544 100644 --- a/test/perftest/CMakeLists.txt +++ b/test/perftest/CMakeLists.txt @@ -19,6 +19,8 @@ if(CCACHE_FOUND) endif() endif(CCACHE_FOUND) +set_property(DIRECTORY PROPERTY COMPILE_OPTIONS ${EXTRA_CXX_FLAGS}) + IF(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug")) add_test(NAME perftest COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/perftest diff --git a/test/unittest/CMakeLists.txt b/test/unittest/CMakeLists.txt index b3204d6..4e29765 100644 --- a/test/unittest/CMakeLists.txt +++ b/test/unittest/CMakeLists.txt @@ -36,10 +36,9 @@ if(CCACHE_FOUND) endif() endif(CCACHE_FOUND) -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal") -elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough -Weverything") +set_property(DIRECTORY PROPERTY COMPILE_OPTIONS ${EXTRA_CXX_FLAGS}) + +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") # If the user is running a newer version of Clang that includes the # -Wdouble-promotion, we will ignore that warning. if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.7) diff --git a/test/unittest/encodingstest.cpp b/test/unittest/encodingstest.cpp index 67b0391..82cf777 100644 --- a/test/unittest/encodingstest.cpp +++ b/test/unittest/encodingstest.cpp @@ -267,7 +267,7 @@ static unsigned inline decode(unsigned* state, unsigned* codep, unsigned byte) { *codep = (*state != UTF8_ACCEPT) ? (byte & 0x3fu) | (*codep << 6) : - (0xff >> type) & (byte); + (0xffu >> type) & (byte); *state = utf8d[256 + *state + type]; return *state; diff --git a/test/unittest/itoatest.cpp b/test/unittest/itoatest.cpp index b752a6a..2f66bed 100644 --- a/test/unittest/itoatest.cpp +++ b/test/unittest/itoatest.cpp @@ -74,7 +74,7 @@ static void Verify(void(*f)(T, char*), char* (*g)(T, char*)) { VerifyValue(std::numeric_limits::max(), f, g); // 2^n - 1, 2^n, 10^n - 1, 10^n until overflow - for (uint32_t power = 2; power <= 10; power += 8) { + for (int power = 2; power <= 10; power += 8) { T i = 1, last; do { VerifyValue(i - 1, f, g); @@ -86,7 +86,7 @@ static void Verify(void(*f)(T, char*), char* (*g)(T, char*)) { last = i; if (i > static_cast(std::numeric_limits::max() / static_cast(power))) break; - i *= power; + i *= static_cast(power); } while (last < i); } }