From ee2e68f44f7b9ee099f98b668257b5d57a86a695 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 10 Aug 2021 18:14:30 +0100 Subject: Enable numeric conversion warning and fix the fallout --- Jamroot.jam | 1 + lib/compileTimeFormatter.h | 2 +- lib/dbStmt.h | 2 +- lib/dbTypes.h | 12 ++++++++++-- lib/helpers.cpp | 11 +++++++++++ lib/helpers.h | 11 +++++++++-- lib/input/mysqlBindings.h | 8 ++++++-- lib/mysql_types.cpp | 26 +++++++++++++------------- lib/output/pq/pqRecordSet.cpp | 4 ++-- lib/output/pq/pqStmt.cpp | 2 +- lib/output/pq/writePqCopyStrm.cpp | 4 ++-- lib/streamSupport.cpp | 2 +- test/test-postgresql.cpp | 2 +- 13 files changed, 59 insertions(+), 28 deletions(-) create mode 100644 lib/helpers.cpp diff --git a/Jamroot.jam b/Jamroot.jam index c85ea56..bf471aa 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -21,6 +21,7 @@ project : requirements release:on debug:extra debug:on + debug:-Wconversion coverage:on tidy:boost-* tidy:bugprone-* diff --git a/lib/compileTimeFormatter.h b/lib/compileTimeFormatter.h index e45a3d9..647fb30 100644 --- a/lib/compileTimeFormatter.h +++ b/lib/compileTimeFormatter.h @@ -133,7 +133,7 @@ namespace MyGrate { template static inline void - appendStream(stream & s, const char_type * p, size_t n) + appendStream(stream & s, const char_type * p, std::streamsize n) { s.write(p, n); } diff --git a/lib/dbStmt.h b/lib/dbStmt.h index 44ab62c..a6d4a65 100644 --- a/lib/dbStmt.h +++ b/lib/dbStmt.h @@ -26,7 +26,7 @@ namespace MyGrate { const auto pn = [](const char * c, const char * const e) { std::size_t n {0}; while (++c != e && *c >= '0' && *c <= '9') { - n = (n * 10) + (*c - '0'); + n = (n * 10) + unsigned(*c - '0'); } return n; }; diff --git a/lib/dbTypes.h b/lib/dbTypes.h index f49c929..e17315b 100644 --- a/lib/dbTypes.h +++ b/lib/dbTypes.h @@ -46,7 +46,11 @@ namespace MyGrate { struct Date { inline Date() { } inline Date(uint16_t y, uint8_t m, uint8_t d) : year {y}, month {m}, day {d} { } - explicit inline Date(const tm & tm) : Date(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday) { } + explicit inline Date(const tm & tm) : + Date(boost::numeric_cast(tm.tm_year + 1900), boost::numeric_cast(tm.tm_mon + 1), + boost::numeric_cast(tm.tm_mday)) + { + } uint16_t year; uint8_t month; uint8_t day; @@ -54,7 +58,11 @@ namespace MyGrate { struct Time { inline Time() { } inline Time(uint8_t h, uint8_t m, uint8_t s) : hour {h}, minute {m}, second {s} { } - explicit inline Time(const tm & tm) : Time(tm.tm_hour, tm.tm_min, tm.tm_sec) { } + explicit inline Time(const tm & tm) : + Time(boost::numeric_cast(tm.tm_hour), boost::numeric_cast(tm.tm_min), + boost::numeric_cast(tm.tm_sec)) + { + } uint8_t hour; uint8_t minute; uint8_t second; diff --git a/lib/helpers.cpp b/lib/helpers.cpp new file mode 100644 index 0000000..23cec2a --- /dev/null +++ b/lib/helpers.cpp @@ -0,0 +1,11 @@ +#include "helpers.h" + +namespace MyGrate { + static_assert(std::is_same_v, uint8_t>); + static_assert(std::is_same_v, uint8_t>); + static_assert(std::is_same_v, uint16_t>); + static_assert(std::is_same_v, uint16_t>); + static_assert(std::is_same_v, uint32_t>); + static_assert(std::is_same_v, uint32_t>); + static_assert(std::is_same_v, uint64_t>); +} diff --git a/lib/helpers.h b/lib/helpers.h index f09a206..2c7f4c2 100644 --- a/lib/helpers.h +++ b/lib/helpers.h @@ -1,6 +1,7 @@ #ifndef MYGRATE_HELPERS_H #define MYGRATE_HELPERS_H +#include #include #include #include @@ -8,8 +9,13 @@ #include namespace MyGrate { + template + using SmallestUInt = std::conditional_t>>; + + template constexpr inline auto - bitslice(const std::integral auto i, uint8_t offset, uint8_t size) + bitslice(const std::integral auto i, uint8_t offset) -> SmallestUInt { return (i >> offset) & ((1U << size) - 1U); } @@ -27,7 +33,8 @@ namespace MyGrate { constexpr inline auto mod100_extract(std::integral auto & i) { - const auto r {i % 100}; + using R = std::conditional_t, int8_t, uint8_t>; + const auto r {boost::numeric_cast(i % 100)}; i /= 100; return r; } diff --git a/lib/input/mysqlBindings.h b/lib/input/mysqlBindings.h index 3d1ad7f..36ef2bf 100644 --- a/lib/input/mysqlBindings.h +++ b/lib/input/mysqlBindings.h @@ -159,11 +159,15 @@ namespace MyGrate::Input { private: operator Date() const { - return Date(buf.year, buf.month, buf.day); + return Date(boost::numeric_cast(buf.year), + boost::numeric_cast(buf.month), + boost::numeric_cast(buf.day)); } operator Time() const { - return Time(buf.hour, buf.minute, buf.second); + return Time(boost::numeric_cast(buf.hour), + boost::numeric_cast(buf.minute), + boost::numeric_cast(buf.second)); } operator DateTime() const { diff --git a/lib/mysql_types.cpp b/lib/mysql_types.cpp index a4641ba..41dbb6e 100644 --- a/lib/mysql_types.cpp +++ b/lib/mysql_types.cpp @@ -16,11 +16,11 @@ namespace MyGrate::MySQL { #define INTEGER_TYPE(ET) \ typename Type::C Type::read(RawDataReader &, RawDataReader & data) \ { \ - return data.readValue::C>(); \ + return data.readValue::C>(); \ } \ typename Type::C Type::read(RawDataReader &, RawDataReader & data) \ { \ - return data.readValue::C>(); \ + return data.readValue::C>(); \ } INTEGER_TYPE(MYSQL_TYPE_TINY); INTEGER_TYPE(MYSQL_TYPE_SHORT); @@ -138,7 +138,7 @@ namespace MyGrate::MySQL { dt.hour = mod100_extract(dtint); dt.day = mod100_extract(dtint); dt.month = mod100_extract(dtint); - dt.year = dtint; + dt.year = boost::numeric_cast(dtint); return dt; } @@ -149,7 +149,7 @@ namespace MyGrate::MySQL { Time t {}; t.second = mod100_extract(tint); t.minute = mod100_extract(tint); - t.hour = tint; + t.hour = boost::numeric_cast(tint); return t; } @@ -164,9 +164,9 @@ namespace MyGrate::MySQL { { auto dint {data.readValue()}; Date d {}; - d.day = bitslice(dint, 0, 6); - d.month = bitslice(dint, 6, 4); - d.year = bitslice(dint, 10, 14); + d.day = bitslice<6>(dint, 0); + d.month = bitslice<4>(dint, 6); + d.year = bitslice<14>(dint, 10); return d; } @@ -201,12 +201,12 @@ namespace MyGrate::MySQL { std::reverse(r.b.begin(), r.b.end()); DateTime dt; - dt.year = (bitslice(r.i, 22, 17) / 13); - dt.month = (bitslice(r.i, 22, 17) % 13); - dt.day = bitslice(r.i, 17, 5); - dt.hour = bitslice(r.i, 12, 5); - dt.minute = bitslice(r.i, 6, 6); - dt.second = bitslice(r.i, 0, 6); + dt.year = boost::numeric_cast(bitslice<17>(r.i, 22) / 13); + dt.month = boost::numeric_cast(bitslice<17>(r.i, 22) % 13); + dt.day = bitslice<5>(r.i, 17); + dt.hour = bitslice<5>(r.i, 12); + dt.minute = bitslice<6>(r.i, 6); + dt.second = bitslice<6>(r.i, 0); return dt; } } diff --git a/lib/output/pq/pqRecordSet.cpp b/lib/output/pq/pqRecordSet.cpp index 71ddee4..e25c571 100644 --- a/lib/output/pq/pqRecordSet.cpp +++ b/lib/output/pq/pqRecordSet.cpp @@ -18,13 +18,13 @@ namespace MyGrate::Output::Pq { std::size_t PqRecordSet::rows() const { - return PQntuples(res.get()); + return boost::numeric_cast(PQntuples(res.get())); } std::size_t PqRecordSet::columns() const { - return PQnfields(res.get()); + return boost::numeric_cast(PQnfields(res.get())); } DbValue diff --git a/lib/output/pq/pqStmt.cpp b/lib/output/pq/pqStmt.cpp index eb3c32d..c6399e4 100644 --- a/lib/output/pq/pqStmt.cpp +++ b/lib/output/pq/pqStmt.cpp @@ -53,7 +53,7 @@ namespace MyGrate::Output::Pq { if (const auto i = c->stmts.find(q); i != c->stmts.end()) { return i->second; } - auto nam {scprintf<"pst%0x">(c->stmts.size())}; + auto nam {scprintf<"pst%0lx">(c->stmts.size())}; ResPtr res {PQprepare(c->conn.get(), nam.c_str(), q, (int)n, nullptr), PQclear}; verify(PQresultStatus(res.get()) == PGRES_COMMAND_OK, q, c->conn.get()); return c->stmts.emplace(q, std::move(nam)).first->second; diff --git a/lib/output/pq/writePqCopyStrm.cpp b/lib/output/pq/writePqCopyStrm.cpp index 4664e6b..984b4fd 100644 --- a/lib/output/pq/writePqCopyStrm.cpp +++ b/lib/output/pq/writePqCopyStrm.cpp @@ -56,7 +56,7 @@ namespace MyGrate::Output::Pq { return std::iscntrl(c); }); if (esc != pos) { - fwrite(pos, esc - pos, 1, out); + fwrite(pos, boost::numeric_cast(esc - pos), 1, out); pos = esc; } while (pos != v.end() && std::iscntrl(*pos)) { @@ -77,7 +77,7 @@ namespace MyGrate::Output::Pq { static constexpr const auto hex {[] { std::array, 256> h {}; std::array hc {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - for (int x {}; x < 256; x += 1) { + for (decltype(h)::size_type x {}; x < 256; x += 1) { h[x] = {hc[x >> 4], hc[x & 0xF]}; } return h; diff --git a/lib/streamSupport.cpp b/lib/streamSupport.cpp index f3c88cf..433fb83 100644 --- a/lib/streamSupport.cpp +++ b/lib/streamSupport.cpp @@ -31,7 +31,7 @@ namespace std { std::ostream & operator<<(std::ostream & s, const timespec & ts) { - return MyGrate::scprintf<"%d.%09d">(s, ts.tv_sec, ts.tv_nsec); + return MyGrate::scprintf<"%ld.%09ld">(s, ts.tv_sec, ts.tv_nsec); } std::ostream & diff --git a/test/test-postgresql.cpp b/test/test-postgresql.cpp index 727e08c..dda05ca 100644 --- a/test/test-postgresql.cpp +++ b/test/test-postgresql.cpp @@ -134,7 +134,7 @@ using FloatTypes = boost::mpl::list; BOOST_AUTO_TEST_CASE_TEMPLATE(write_floats, T, FloatTypes) { MyGrate::Output::Pq::WritePqCopyStream c {s}; - c(T {1.1}); + c(T {1.1F}); flush(); BOOST_REQUIRE(out); -- cgit v1.2.3