compilerplugins/clang/unusedmember.cxx | 4 + sal/rtl/math.cxx | 86 ++++++++++++++++----------------- 2 files changed, 46 insertions(+), 44 deletions(-)
New commits: commit b8ddec4d4a95eab650885911db58e15e79a0d038 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Thu Sep 18 12:54:03 2025 +0500 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Sep 26 08:54:03 2025 +0200 Encapsulate buffer management in stringToDouble Use a struct for that, and its 'insert' method, to avoid repeating code, and make the logic more transparent. Change-Id: I90fd4879e1b680ededc3aa4692fb6f59eeb5916c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191144 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins (cherry picked from commit daded1002cfd511763976644eb2a29454049e33f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191298 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/compilerplugins/clang/unusedmember.cxx b/compilerplugins/clang/unusedmember.cxx index 610c94e162b3..57b5f50986a4 100644 --- a/compilerplugins/clang/unusedmember.cxx +++ b/compilerplugins/clang/unusedmember.cxx @@ -209,6 +209,8 @@ public: } } } + if (suppressWarningAt(d->getLocation())) + return true; report(DiagnosticsEngine::Warning, "unused class member", d->getLocation()) << d->getSourceRange(); } @@ -375,6 +377,8 @@ public: continue; } } + if (suppressWarningAt(d->getLocation())) + continue; report(DiagnosticsEngine::Warning, "unused class member", d->getLocation()) << d->getSourceRange(); } diff --git a/sal/rtl/math.cxx b/sal/rtl/math.cxx index 596e5ad7a086..ce1239eb7b69 100644 --- a/sal/rtl/math.cxx +++ b/sal/rtl/math.cxx @@ -220,35 +220,46 @@ double stringToDouble(CharT const* pBegin, CharT const* pEnd, CharT cDecSeparato if (!bDone) // do not recognize e.g. NaN1.23 { - std::unique_ptr<char[]> bufInHeap; - std::unique_ptr<const CharT* []> bufInHeapMap; - constexpr int bufOnStackSize = 256; - char bufOnStack[bufOnStackSize]; - const CharT* bufOnStackMap[bufOnStackSize]; - char* buf = bufOnStack; - const CharT** bufmap = bufOnStackMap; - int bufpos = 0; - const size_t bufsize = pEnd - p + (bSign ? 2 : 1); - if (bufsize > bufOnStackSize) + // Stores a normalized number string for final conversion, plus a map from each position + // in the normalized string to the corresponding position in the original string + struct Buf_t { - bufInHeap = std::make_unique<char[]>(bufsize); - bufInHeapMap = std::make_unique<const CharT* []>(bufsize); - buf = bufInHeap.get(); - bufmap = bufInHeapMap.get(); - } + std::unique_ptr<char[]> stringInHeap; + std::unique_ptr<const CharT* []> mapInHeap; + char stringOnStack[256]; + const CharT* mapOnStack[256]; + char* string = stringOnStack; + const CharT** map = mapOnStack; + size_t pos = 0; + // [-loplugin:unusedmember] false positive + Buf_t(size_t bufsize) + { + if (bufsize > 256) + { + stringInHeap = std::make_unique<char[]>(bufsize); + mapInHeap = std::make_unique<const CharT* []>(bufsize); + string = stringInHeap.get(); + map = mapInHeap.get(); + } + } + // [-loplugin:unusedmember] false positive + void insert(char c, const CharT* ptr) + { + string[pos] = c; + map[pos] = ptr; + ++pos; + } + }; + Buf_t buf(pEnd - p + (bSign ? 2 : 1)); if (bSign) { - buf[0] = '-'; - bufmap[0] = p; // yes, this may be the same pointer as for the next mapping - bufpos = 1; + buf.insert('-', p); // yes, this may be the same pointer as for the next mapping } // Put first zero to buffer for strings like "-0" if (p != pEnd && *p == '0') { - buf[bufpos] = '0'; - bufmap[bufpos] = p; - ++bufpos; + buf.insert('0', p); ++p; } // Leading zeros and group separators between digits may be safely @@ -269,9 +280,7 @@ double stringToDouble(CharT const* pBegin, CharT const* pEnd, CharT cDecSeparato CharT c = *p; if (rtl::isAsciiDigit(c)) { - buf[bufpos] = static_cast<char>(c); - bufmap[bufpos] = p; - ++bufpos; + buf.insert(c, p); } else if (c != cGroupSeparator) { @@ -288,9 +297,7 @@ double stringToDouble(CharT const* pBegin, CharT const* pEnd, CharT cDecSeparato // fraction part of mantissa if (p != pEnd && *p == cDecSeparator) { - buf[bufpos] = '.'; - bufmap[bufpos] = p; - ++bufpos; + buf.insert('.', p); ++p; for (; p != pEnd; ++p) @@ -300,24 +307,18 @@ double stringToDouble(CharT const* pBegin, CharT const* pEnd, CharT cDecSeparato { break; } - buf[bufpos] = static_cast<char>(c); - bufmap[bufpos] = p; - ++bufpos; + buf.insert(c, p); } } // Exponent if (p != p0 && p != pEnd && (*p == 'E' || *p == 'e')) { - buf[bufpos] = 'E'; - bufmap[bufpos] = p; - ++bufpos; + buf.insert('E', p); ++p; if (p != pEnd && *p == '-') { - buf[bufpos] = '-'; - bufmap[bufpos] = p; - ++bufpos; + buf.insert('-', p); ++p; } else if (p != pEnd && *p == '+') @@ -329,9 +330,7 @@ double stringToDouble(CharT const* pBegin, CharT const* pEnd, CharT cDecSeparato if (!rtl::isAsciiDigit(c)) break; - buf[bufpos] = static_cast<char>(c); - bufmap[bufpos] = p; - ++bufpos; + buf.insert(c, p); } } else if (p - p0 == 2 && p != pEnd && p[0] == '#' && p[-1] == cDecSeparator && p[-2] == '1') @@ -365,11 +364,10 @@ double stringToDouble(CharT const* pBegin, CharT const* pEnd, CharT cDecSeparato if (!bDone) { - buf[bufpos] = ' - bufmap[bufpos] = p; + buf.insert(' char* pCharParseEnd; errno = 0; - fVal = strtod_nolocale(buf, &pCharParseEnd); + fVal = strtod_nolocale(buf.string, &pCharParseEnd); if (errno == ERANGE) { // This happens with overflow and underflow (including subnormals!) @@ -378,7 +376,7 @@ double stringToDouble(CharT const* pBegin, CharT const* pEnd, CharT cDecSeparato // Check for the dreaded rounded to 15 digits max value // 1.79769313486232e+308 for 1.7976931348623157e+308 we wrote // everywhere, accept with or without plus sign in exponent. - std::string_view num_view(buf, pCharParseEnd - buf); + std::string_view num_view(buf.string, pCharParseEnd - buf.string); if (num_view == "1.79769313486232E308") { fVal = DBL_MAX; @@ -398,7 +396,7 @@ double stringToDouble(CharT const* pBegin, CharT const* pEnd, CharT cDecSeparato } // else it's subnormal: allow it } - p = bufmap[pCharParseEnd - buf]; + p = buf.map[pCharParseEnd - buf.string]; bSign = false; } }