diff --git a/CMakeLists.txt b/CMakeLists.txt index 698133f..1f4c1f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,10 +103,10 @@ endif() if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") # using regular Clang or AppleClang - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wconversion -Wshadow -Wno-sign-conversion") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wconversion -Wshadow -Wno-sign-conversion -Werror=conversion") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # using GCC - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wconversion -Wshadow -Wextra") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wconversion -Wshadow -Wextra -Werror=conversion") # not yet ready for -Wsign-conversion if (JSONCPP_WITH_STRICT_ISO AND NOT JSONCPP_WITH_WARNING_AS_ERROR) diff --git a/include/json/reader.h b/include/json/reader.h index 0a1574f..70d9505 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -42,8 +42,8 @@ public: * */ struct StructuredError { - size_t offset_start; - size_t offset_limit; + ptrdiff_t offset_start; + ptrdiff_t offset_limit; std::string message; }; diff --git a/include/json/value.h b/include/json/value.h index 1cfda07..b3f1ceb 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -554,10 +554,10 @@ Json::Value obj_value(Json::objectValue); // {} // Accessors for the [start, limit) range of bytes within the JSON text from // which this value was parsed, if any. - void setOffsetStart(size_t start); - void setOffsetLimit(size_t limit); - size_t getOffsetStart() const; - size_t getOffsetLimit() const; + void setOffsetStart(ptrdiff_t start); + void setOffsetLimit(ptrdiff_t limit); + ptrdiff_t getOffsetStart() const; + ptrdiff_t getOffsetLimit() const; private: void initBasic(ValueType type, bool allocated = false); @@ -598,8 +598,8 @@ private: // [start, limit) byte offsets in the source JSON text from which this Value // was extracted. - size_t start_; - size_t limit_; + ptrdiff_t start_; + ptrdiff_t limit_; }; /** \brief Experimental and untested: represents an element of the "path" to diff --git a/include/json/writer.h b/include/json/writer.h index f94aa1f..180ab68 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -238,8 +238,8 @@ private: ChildValues childValues_; std::string document_; std::string indentString_; - int rightMargin_; - int indentSize_; + unsigned int rightMargin_; + unsigned int indentSize_; bool addChildValues_; }; diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index c8bbd0d..35e4ea1 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -57,12 +57,13 @@ static std::string readInputTestFile(const char* path) { if (!file) return std::string(""); fseek(file, 0, SEEK_END); - long size = ftell(file); + long const size = ftell(file); + unsigned long const usize = static_cast(size); fseek(file, 0, SEEK_SET); std::string text; char* buffer = new char[size + 1]; buffer[size] = 0; - if (fread(buffer, 1, size, file) == (unsigned long)size) + if (fread(buffer, 1, usize, file) == usize) text = buffer; fclose(file); delete[] buffer; @@ -104,8 +105,8 @@ printValueTree(FILE* fout, Json::Value& value, const std::string& path = ".") { break; case Json::arrayValue: { fprintf(fout, "%s=[]\n", path.c_str()); - int size = value.size(); - for (int index = 0; index < size; ++index) { + Json::ArrayIndex size = value.size(); + for (Json::ArrayIndex index = 0; index < size; ++index) { static char buffer[16]; #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) sprintf_s(buffer, sizeof(buffer), "[%d]", index); diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 2eae15d..fec0342 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -368,7 +368,7 @@ bool Reader::readComment() { static std::string normalizeEOL(Reader::Location begin, Reader::Location end) { std::string normalized; - normalized.reserve(end - begin); + normalized.reserve(static_cast(end - begin)); Reader::Location current = begin; while (current != end) { char c = *current++; @@ -578,7 +578,7 @@ bool Reader::decodeNumber(Token& token, Value& decoded) { Char c = *current++; if (c < '0' || c > '9') return decodeDouble(token, decoded); - Value::UInt digit(c - '0'); + Value::UInt digit(static_cast(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If // a) we've only just touched the limit, b) this is the last digit, and @@ -636,7 +636,7 @@ bool Reader::decodeString(Token& token) { } bool Reader::decodeString(Token& token, std::string& decoded) { - decoded.reserve(token.end_ - token.start_ - 2); + decoded.reserve(static_cast(token.end_ - token.start_ - 2)); Location current = token.start_ + 1; // skip '"' Location end = token.end_ - 1; // do not include '"' while (current != end) { @@ -720,13 +720,13 @@ bool Reader::decodeUnicodeCodePoint(Token& token, bool Reader::decodeUnicodeEscapeSequence(Token& token, Location& current, Location end, - unsigned int& unicode) { + unsigned int& ret_unicode) { if (end - current < 4) return addError( "Bad unicode escape sequence in string: four digits expected.", token, current); - unicode = 0; + int unicode = 0; for (int index = 0; index < 4; ++index) { Char c = *current++; unicode *= 16; @@ -742,6 +742,7 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token, token, current); } + ret_unicode = static_cast(unicode); return true; } @@ -756,7 +757,7 @@ Reader::addError(const std::string& message, Token& token, Location extra) { } bool Reader::recoverFromError(TokenType skipUntilToken) { - int errorCount = int(errors_.size()); + size_t const errorCount = errors_.size(); Token skip; for (;;) { if (!readToken(skip)) @@ -851,7 +852,7 @@ std::vector Reader::getStructuredErrors() const { } bool Reader::pushError(const Value& value, const std::string& message) { - size_t length = end_ - begin_; + ptrdiff_t const length = end_ - begin_; if(value.getOffsetStart() > length || value.getOffsetLimit() > length) return false; @@ -868,7 +869,7 @@ bool Reader::pushError(const Value& value, const std::string& message) { } bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) { - size_t length = end_ - begin_; + ptrdiff_t const length = end_ - begin_; if(value.getOffsetStart() > length || value.getOffsetLimit() > length || extra.getOffsetLimit() > length) @@ -918,8 +919,8 @@ public: typedef char Char; typedef const Char* Location; struct StructuredError { - size_t offset_start; - size_t offset_limit; + ptrdiff_t offset_start; + ptrdiff_t offset_limit; std::string message; }; @@ -1560,7 +1561,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { Char c = *current++; if (c < '0' || c > '9') return decodeDouble(token, decoded); - Value::UInt digit(c - '0'); + Value::UInt digit(static_cast(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If // a) we've only just touched the limit, b) this is the last digit, and @@ -1596,12 +1597,13 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) { double value = 0; const int bufferSize = 32; int count; - int length = int(token.end_ - token.start_); + ptrdiff_t const length = token.end_ - token.start_; // Sanity check to avoid buffer overflow exploits. if (length < 0) { return addError("Unable to parse token length", token); } + size_t const ulength = static_cast(length); // Avoid using a string constant for the format control string given to // sscanf, as this can cause hard to debug crashes on OS X. See here for more @@ -1612,7 +1614,7 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) { if (length <= bufferSize) { Char buffer[bufferSize + 1]; - memcpy(buffer, token.start_, length); + memcpy(buffer, token.start_, ulength); buffer[length] = 0; count = sscanf(buffer, format, &value); } else { @@ -1640,7 +1642,7 @@ bool OurReader::decodeString(Token& token) { } bool OurReader::decodeString(Token& token, std::string& decoded) { - decoded.reserve(token.end_ - token.start_ - 2); + decoded.reserve(static_cast(token.end_ - token.start_ - 2)); Location current = token.start_ + 1; // skip '"' Location end = token.end_ - 1; // do not include '"' while (current != end) { @@ -1724,13 +1726,13 @@ bool OurReader::decodeUnicodeCodePoint(Token& token, bool OurReader::decodeUnicodeEscapeSequence(Token& token, Location& current, Location end, - unsigned int& unicode) { + unsigned int& ret_unicode) { if (end - current < 4) return addError( "Bad unicode escape sequence in string: four digits expected.", token, current); - unicode = 0; + int unicode = 0; for (int index = 0; index < 4; ++index) { Char c = *current++; unicode *= 16; @@ -1746,6 +1748,7 @@ bool OurReader::decodeUnicodeEscapeSequence(Token& token, token, current); } + ret_unicode = static_cast(unicode); return true; } @@ -1760,7 +1763,7 @@ OurReader::addError(const std::string& message, Token& token, Location extra) { } bool OurReader::recoverFromError(TokenType skipUntilToken) { - int errorCount = int(errors_.size()); + size_t errorCount = errors_.size(); Token skip; for (;;) { if (!readToken(skip)) @@ -1850,7 +1853,7 @@ std::vector OurReader::getStructuredErrors() const { } bool OurReader::pushError(const Value& value, const std::string& message) { - size_t length = end_ - begin_; + ptrdiff_t length = end_ - begin_; if(value.getOffsetStart() > length || value.getOffsetLimit() > length) return false; @@ -1867,7 +1870,7 @@ bool OurReader::pushError(const Value& value, const std::string& message) { } bool OurReader::pushError(const Value& value, const std::string& message, const Value& extra) { - size_t length = end_ - begin_; + ptrdiff_t length = end_ - begin_; if(value.getOffsetStart() > length || value.getOffsetLimit() > length || extra.getOffsetLimit() > length) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 91b5f23..a1962e6 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -55,6 +55,9 @@ const LargestUInt Value::maxLargestUInt = LargestUInt(-1); #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) template static inline bool InRange(double d, T min, U max) { + // The casts can lose precision, but we are looking only for + // an approximate range. Might fail on edge cases though. ~cdunn + //return d >= static_cast(min) && d <= static_cast(max); return d >= min && d <= max; } #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) @@ -1332,13 +1335,13 @@ std::string Value::getComment(CommentPlacement placement) const { return ""; } -void Value::setOffsetStart(size_t start) { start_ = start; } +void Value::setOffsetStart(ptrdiff_t start) { start_ = start; } -void Value::setOffsetLimit(size_t limit) { limit_ = limit; } +void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; } -size_t Value::getOffsetStart() const { return start_; } +ptrdiff_t Value::getOffsetStart() const { return start_; } -size_t Value::getOffsetLimit() const { return limit_; } +ptrdiff_t Value::getOffsetLimit() const { return limit_; } std::string Value::toStyledString() const { StyledWriter writer; diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 0b2d7d5..f7ceedc 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -361,8 +361,8 @@ void FastWriter::writeValue(const Value& value) { break; case arrayValue: { document_ += '['; - int size = value.size(); - for (int index = 0; index < size; ++index) { + ArrayIndex size = value.size(); + for (ArrayIndex index = 0; index < size; ++index) { if (index > 0) document_ += ','; writeValue(value[index]); @@ -506,10 +506,10 @@ void StyledWriter::writeArrayValue(const Value& value) { } bool StyledWriter::isMultineArray(const Value& value) { - int size = value.size(); + ArrayIndex const size = value.size(); bool isMultiLine = size * 3 >= rightMargin_; childValues_.clear(); - for (int index = 0; index < size && !isMultiLine; ++index) { + for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { const Value& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && childValue.size() > 0); @@ -518,13 +518,13 @@ bool StyledWriter::isMultineArray(const Value& value) { { childValues_.reserve(size); addChildValues_ = true; - int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' - for (int index = 0; index < size; ++index) { + ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + for (ArrayIndex index = 0; index < size; ++index) { if (hasCommentForValue(value[index])) { isMultiLine = true; } writeValue(value[index]); - lineLength += int(childValues_[index].length()); + lineLength += childValues_[index].length(); } addChildValues_ = false; isMultiLine = isMultiLine || lineLength >= rightMargin_; @@ -725,10 +725,10 @@ void StyledStreamWriter::writeArrayValue(const Value& value) { } bool StyledStreamWriter::isMultineArray(const Value& value) { - int size = value.size(); + ArrayIndex const size = value.size(); bool isMultiLine = size * 3 >= rightMargin_; childValues_.clear(); - for (int index = 0; index < size && !isMultiLine; ++index) { + for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { const Value& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && childValue.size() > 0); @@ -737,13 +737,13 @@ bool StyledStreamWriter::isMultineArray(const Value& value) { { childValues_.reserve(size); addChildValues_ = true; - int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' - for (int index = 0; index < size; ++index) { + ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + for (ArrayIndex index = 0; index < size; ++index) { if (hasCommentForValue(value[index])) { isMultiLine = true; } writeValue(value[index]); - lineLength += int(childValues_[index].length()); + lineLength += childValues_[index].length(); } addChildValues_ = false; isMultiLine = isMultiLine || lineLength >= rightMargin_; @@ -1008,10 +1008,10 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) { } bool BuiltStyledStreamWriter::isMultineArray(Value const& value) { - int size = value.size(); + ArrayIndex const size = value.size(); bool isMultiLine = size * 3 >= rightMargin_; childValues_.clear(); - for (int index = 0; index < size && !isMultiLine; ++index) { + for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { Value const& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && childValue.size() > 0); @@ -1020,13 +1020,13 @@ bool BuiltStyledStreamWriter::isMultineArray(Value const& value) { { childValues_.reserve(size); addChildValues_ = true; - int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' - for (int index = 0; index < size; ++index) { + ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + for (ArrayIndex index = 0; index < size; ++index) { if (hasCommentForValue(value[index])) { isMultiLine = true; } writeValue(value[index]); - lineLength += int(childValues_[index].length()); + lineLength += childValues_[index].length(); } addChildValues_ = false; isMultiLine = isMultiLine || lineLength >= rightMargin_;