Treat signed-unsigned conversions as errors.

parent 835f2f4a
...@@ -57,6 +57,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") ...@@ -57,6 +57,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
endif() endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror") 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 (RAPIDJSON_BUILD_CXX11)
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7.0") if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7.0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
...@@ -86,6 +87,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") ...@@ -86,6 +87,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
endif() endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -Wno-missing-field-initializers") 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) if (RAPIDJSON_BUILD_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif() endif()
......
...@@ -24,11 +24,10 @@ set(EXAMPLES ...@@ -24,11 +24,10 @@ set(EXAMPLES
include_directories("../include/") include_directories("../include/")
add_definitions(-D__STDC_FORMAT_MACROS) add_definitions(-D__STDC_FORMAT_MACROS)
set_property(DIRECTORY PROPERTY COMPILE_OPTIONS ${EXTRA_CXX_FLAGS})
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -Werror -Wall -Wextra -Weffc++ -Wswitch-default") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
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")
endif() endif()
foreach (example ${EXAMPLES}) foreach (example ${EXAMPLES})
......
...@@ -200,7 +200,7 @@ private: ...@@ -200,7 +200,7 @@ private:
// xx xx xx xx UTF-8 // xx xx xx xx UTF-8
if (!hasBOM_) { 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) { switch (pattern) {
case 0x08: type_ = kUTF32BE; break; case 0x08: type_ = kUTF32BE; break;
case 0x0A: type_ = kUTF16BE; break; case 0x0A: type_ = kUTF16BE; break;
......
...@@ -157,7 +157,7 @@ struct UTF8 { ...@@ -157,7 +157,7 @@ struct UTF8 {
if (type >= 32) { if (type >= 32) {
*codepoint = 0; *codepoint = 0;
} else { } else {
*codepoint = (0xFF >> type) & static_cast<unsigned char>(c); *codepoint = (0xFFu >> type) & static_cast<unsigned char>(c);
} }
bool result = true; bool result = true;
switch (type) { switch (type) {
...@@ -283,7 +283,7 @@ struct UTF16 { ...@@ -283,7 +283,7 @@ struct UTF16 {
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
unsigned v = codepoint - 0x10000; unsigned v = codepoint - 0x10000;
os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800)); os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
os.Put((v & 0x3FF) | 0xDC00); os.Put(static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
} }
} }
...@@ -299,7 +299,7 @@ struct UTF16 { ...@@ -299,7 +299,7 @@ struct UTF16 {
RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
unsigned v = codepoint - 0x10000; unsigned v = codepoint - 0x10000;
PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800)); PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
PutUnsafe(os, (v & 0x3FF) | 0xDC00); PutUnsafe(os, static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
} }
} }
......
...@@ -41,7 +41,7 @@ inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uin ...@@ -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. // Simple pure C++ implementation was faster than __builtin_clz version in this situation.
if (n < 10) return 1; if (n < 10) return 1;
if (n < 100) return 2; if (n < 100) return 2;
...@@ -63,7 +63,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff ...@@ -63,7 +63,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
const DiyFp wp_w = Mp - W; const DiyFp wp_w = Mp - W;
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e); uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
uint64_t p2 = Mp.f & (one.f - 1); 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; *len = 0;
while (kappa > 0) { while (kappa > 0) {
...@@ -102,8 +102,8 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff ...@@ -102,8 +102,8 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
kappa--; kappa--;
if (p2 < delta) { if (p2 < delta) {
*K += kappa; *K += kappa;
int index = -static_cast<int>(kappa); int index = -kappa;
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[-static_cast<int>(kappa)] : 0)); GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[index] : 0));
return; return;
} }
} }
......
...@@ -48,13 +48,13 @@ public: ...@@ -48,13 +48,13 @@ public:
int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }
uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; }
static unsigned EffectiveSignificandSize(int order) { static int EffectiveSignificandSize(int order) {
if (order >= -1021) if (order >= -1021)
return 53; return 53;
else if (order <= -1074) else if (order <= -1074)
return 0; return 0;
else else
return static_cast<unsigned>(order) + 1074; return order + 1074;
} }
private: private:
......
...@@ -688,8 +688,8 @@ private: ...@@ -688,8 +688,8 @@ private:
bool matched = AddState(l, s.out); bool matched = AddState(l, s.out);
return AddState(l, s.out1) || matched; return AddState(l, s.out1) || matched;
} }
else if (!(stateSet_[index >> 5] & (1 << (index & 31)))) { else if (!(stateSet_[index >> 5] & (1u << (index & 31)))) {
stateSet_[index >> 5] |= (1 << (index & 31)); stateSet_[index >> 5] |= (1u << (index & 31));
*l.template PushUnsafe<SizeType>() = index; *l.template PushUnsafe<SizeType>() = index;
} }
return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation. return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation.
......
...@@ -140,8 +140,8 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit ...@@ -140,8 +140,8 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
significand++; significand++;
size_t remaining = length - i; size_t remaining = length - i;
const unsigned kUlpShift = 3; const int kUlpShift = 3;
const unsigned kUlp = 1 << kUlpShift; const int kUlp = 1 << kUlpShift;
int64_t error = (remaining == 0) ? 0 : kUlp / 2; int64_t error = (remaining == 0) ? 0 : kUlp / 2;
DiyFp v(significand, 0); DiyFp v(significand, 0);
...@@ -177,17 +177,17 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit ...@@ -177,17 +177,17 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
v = v.Normalize(); v = v.Normalize();
error <<= oldExp - v.e; error <<= oldExp - v.e;
const unsigned effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); const int effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e);
unsigned precisionSize = 64 - effectiveSignificandSize; int precisionSize = 64 - effectiveSignificandSize;
if (precisionSize + kUlpShift >= 64) { if (precisionSize + kUlpShift >= 64) {
unsigned scaleExp = (precisionSize + kUlpShift) - 63; int scaleExp = (precisionSize + kUlpShift) - 63;
v.f >>= scaleExp; v.f >>= scaleExp;
v.e += scaleExp; v.e += scaleExp;
error = (error >> scaleExp) + 1 + static_cast<int>(kUlp); error = (error >> scaleExp) + 1 + kUlp;
precisionSize -= scaleExp; precisionSize -= scaleExp;
} }
DiyFp rounded(v.f >> precisionSize, v.e + static_cast<int>(precisionSize)); DiyFp rounded(v.f >> precisionSize, v.e + precisionSize);
const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp;
const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp;
if (precisionBits >= halfWay + static_cast<unsigned>(error)) { if (precisionBits >= halfWay + static_cast<unsigned>(error)) {
......
...@@ -54,7 +54,7 @@ public: ...@@ -54,7 +54,7 @@ public:
Ch Peek() const { Ch Peek() const {
typename StreamType::int_type c = stream_.peek(); typename StreamType::int_type c = stream_.peek();
return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast<Ch>(c) : '\0'; return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast<Ch>(c) : static_cast<Ch>('\0');
} }
Ch Take() { Ch Take() {
......
...@@ -274,7 +274,7 @@ public: ...@@ -274,7 +274,7 @@ public:
else { else {
Ch name[21]; Ch name[21];
for (size_t i = 0; i <= length; i++) for (size_t i = 0; i <= length; i++)
name[i] = buffer[i]; name[i] = static_cast<Ch>(buffer[i]);
Token token = { name, length, index }; Token token = { name, length, index };
return Append(token, allocator); return Append(token, allocator);
} }
...@@ -1029,8 +1029,8 @@ private: ...@@ -1029,8 +1029,8 @@ private:
unsigned char u = static_cast<unsigned char>(c); unsigned char u = static_cast<unsigned char>(c);
static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 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('%');
os_.Put(hexDigits[u >> 4]); os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
os_.Put(hexDigits[u & 15]); os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
} }
private: private:
OutputStream& os_; OutputStream& os_;
......
...@@ -1263,7 +1263,7 @@ struct TokenHelper { ...@@ -1263,7 +1263,7 @@ struct TokenHelper {
char buffer[21]; char buffer[21];
size_t length = static_cast<size_t>((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer); size_t length = static_cast<size_t>((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer);
for (size_t i = 0; i < length; i++) for (size_t i = 0; i < length; i++)
*documentStack.template Push<Ch>() = buffer[i]; *documentStack.template Push<Ch>() = static_cast<Ch>(buffer[i]);
} }
}; };
......
...@@ -352,7 +352,7 @@ protected: ...@@ -352,7 +352,7 @@ protected:
char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
PutReserve(*os_, static_cast<size_t>(end - buffer)); PutReserve(*os_, static_cast<size_t>(end - buffer));
for (char* p = buffer; p != end; ++p) for (char* p = buffer; p != end; ++p)
PutUnsafe(*os_, static_cast<typename TargetEncoding::Ch>(*p)); PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));
return true; return true;
} }
......
...@@ -19,6 +19,8 @@ if(CCACHE_FOUND) ...@@ -19,6 +19,8 @@ if(CCACHE_FOUND)
endif() endif()
endif(CCACHE_FOUND) endif(CCACHE_FOUND)
set_property(DIRECTORY PROPERTY COMPILE_OPTIONS ${EXTRA_CXX_FLAGS})
IF(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug")) IF(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug"))
add_test(NAME perftest add_test(NAME perftest
COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/perftest COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/perftest
......
...@@ -36,10 +36,9 @@ if(CCACHE_FOUND) ...@@ -36,10 +36,9 @@ if(CCACHE_FOUND)
endif() endif()
endif(CCACHE_FOUND) endif(CCACHE_FOUND)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set_property(DIRECTORY PROPERTY COMPILE_OPTIONS ${EXTRA_CXX_FLAGS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Weffc++ -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough -Weverything")
# If the user is running a newer version of Clang that includes the # If the user is running a newer version of Clang that includes the
# -Wdouble-promotion, we will ignore that warning. # -Wdouble-promotion, we will ignore that warning.
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.7) if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.7)
......
...@@ -267,7 +267,7 @@ static unsigned inline decode(unsigned* state, unsigned* codep, unsigned byte) { ...@@ -267,7 +267,7 @@ static unsigned inline decode(unsigned* state, unsigned* codep, unsigned byte) {
*codep = (*state != UTF8_ACCEPT) ? *codep = (*state != UTF8_ACCEPT) ?
(byte & 0x3fu) | (*codep << 6) : (byte & 0x3fu) | (*codep << 6) :
(0xff >> type) & (byte); (0xffu >> type) & (byte);
*state = utf8d[256 + *state + type]; *state = utf8d[256 + *state + type];
return *state; return *state;
......
...@@ -74,7 +74,7 @@ static void Verify(void(*f)(T, char*), char* (*g)(T, char*)) { ...@@ -74,7 +74,7 @@ static void Verify(void(*f)(T, char*), char* (*g)(T, char*)) {
VerifyValue<T>(std::numeric_limits<T>::max(), f, g); VerifyValue<T>(std::numeric_limits<T>::max(), f, g);
// 2^n - 1, 2^n, 10^n - 1, 10^n until overflow // 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; T i = 1, last;
do { do {
VerifyValue<T>(i - 1, f, g); VerifyValue<T>(i - 1, f, g);
...@@ -86,7 +86,7 @@ static void Verify(void(*f)(T, char*), char* (*g)(T, char*)) { ...@@ -86,7 +86,7 @@ static void Verify(void(*f)(T, char*), char* (*g)(T, char*)) {
last = i; last = i;
if (i > static_cast<T>(std::numeric_limits<T>::max() / static_cast<T>(power))) if (i > static_cast<T>(std::numeric_limits<T>::max() / static_cast<T>(power)))
break; break;
i *= power; i *= static_cast<T>(power);
} while (last < i); } while (last < i);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment