Bug Summary

File:out/../deps/icu-small/source/i18n/number_utils.cpp
Warning:line 72, column 13
Value stored to 'patternKey' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name number_utils.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D V8_DEPRECATION_WARNINGS -D V8_IMMINENT_DEPRECATION_WARNINGS -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D U_COMMON_IMPLEMENTATION=1 -D U_I18N_IMPLEMENTATION=1 -D U_IO_IMPLEMENTATION=1 -D U_TOOLUTIL_IMPLEMENTATION=1 -D U_ATTRIBUTE_DEPRECATED= -D _CRT_SECURE_NO_DEPRECATE= -D U_STATIC_IMPLEMENTATION=1 -D UCONFIG_NO_SERVICE=1 -D U_ENABLE_DYLOAD=0 -D U_HAVE_STD_STRING=1 -D UCONFIG_NO_BREAK_ITERATION=0 -I ../deps/icu-small/source/common -I ../deps/icu-small/source/i18n -I ../deps/icu-small/source/tools/toolutil -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/backward -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-deprecated-declarations -Wno-strict-aliasing -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c++ ../deps/icu-small/source/i18n/number_utils.cpp
1// © 2018 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3
4#include "unicode/utypes.h"
5
6#if !UCONFIG_NO_FORMATTING0
7
8// Allow implicit conversion from char16_t* to UnicodeString for this file:
9// Helpful in toString methods and elsewhere.
10#define UNISTR_FROM_STRING_EXPLICIT
11
12#include <stdlib.h>
13#include <cmath>
14#include "number_decnum.h"
15#include "number_types.h"
16#include "number_utils.h"
17#include "charstr.h"
18#include "decContext.h"
19#include "decNumber.h"
20#include "double-conversion.h"
21#include "fphdlimp.h"
22#include "uresimp.h"
23#include "ureslocs.h"
24
25using namespace icu;
26using namespace icu::number;
27using namespace icu::number::impl;
28
29using icu::double_conversion::DoubleToStringConverter;
30
31
32namespace {
33
34const char16_t*
35doGetPattern(UResourceBundle* res, const char* nsName, const char* patternKey, UErrorCode& publicStatus,
36 UErrorCode& localStatus) {
37 // Construct the path into the resource bundle
38 CharString key;
39 key.append("NumberElements/", publicStatus);
40 key.append(nsName, publicStatus);
41 key.append("/patterns/", publicStatus);
42 key.append(patternKey, publicStatus);
43 if (U_FAILURE(publicStatus)) {
44 return u"";
45 }
46 return ures_getStringByKeyWithFallbackures_getStringByKeyWithFallback_71(res, key.data(), nullptr, &localStatus);
47}
48
49}
50
51
52const char16_t* utils::getPatternForStyle(const Locale& locale, const char* nsName, CldrPatternStyle style,
53 UErrorCode& status) {
54 const char* patternKey;
55 switch (style) {
56 case CLDR_PATTERN_STYLE_DECIMAL:
57 patternKey = "decimalFormat";
58 break;
59 case CLDR_PATTERN_STYLE_CURRENCY:
60 patternKey = "currencyFormat";
61 break;
62 case CLDR_PATTERN_STYLE_ACCOUNTING:
63 patternKey = "accountingFormat";
64 break;
65 case CLDR_PATTERN_STYLE_PERCENT:
66 patternKey = "percentFormat";
67 break;
68 case CLDR_PATTERN_STYLE_SCIENTIFIC:
69 patternKey = "scientificFormat";
70 break;
71 default:
72 patternKey = "decimalFormat"; // silence compiler error
Value stored to 'patternKey' is never read
73 UPRV_UNREACHABLE_EXITabort();
74 }
75 LocalUResourceBundlePointer res(ures_openures_open_71(nullptr, locale.getName(), &status));
76 if (U_FAILURE(status)) { return u""; }
77
78 // Attempt to get the pattern with the native numbering system.
79 UErrorCode localStatus = U_ZERO_ERROR;
80 const char16_t* pattern;
81 pattern = doGetPattern(res.getAlias(), nsName, patternKey, status, localStatus);
82 if (U_FAILURE(status)) { return u""; }
83
84 // Fall back to latn if native numbering system does not have the right pattern
85 if (U_FAILURE(localStatus) && uprv_strcmp("latn", nsName):: strcmp("latn", nsName) != 0) {
86 localStatus = U_ZERO_ERROR;
87 pattern = doGetPattern(res.getAlias(), "latn", patternKey, status, localStatus);
88 if (U_FAILURE(status)) { return u""; }
89 }
90
91 return pattern;
92}
93
94
95DecNum::DecNum() {
96 uprv_decContextDefaultuprv_decContextDefault_71(&fContext, DEC_INIT_BASE0);
97 uprv_decContextSetRoundinguprv_decContextSetRounding_71(&fContext, DEC_ROUND_HALF_EVEN);
98 fContext.traps = 0; // no traps, thank you (what does this even mean?)
99}
100
101DecNum::DecNum(const DecNum& other, UErrorCode& status)
102 : fContext(other.fContext) {
103 // Allocate memory for the new DecNum.
104 U_ASSERT(fContext.digits == other.fData.getCapacity())(void)0;
105 if (fContext.digits > kDefaultDigits) {
106 void* p = fData.resize(fContext.digits, 0);
107 if (p == nullptr) {
108 status = U_MEMORY_ALLOCATION_ERROR;
109 return;
110 }
111 }
112
113 // Copy the data from the old DecNum to the new one.
114 uprv_memcpy(fData.getAlias(), other.fData.getAlias(), sizeof(decNumber))do { clang diagnostic push clang diagnostic ignored "-Waddress"
(void)0; (void)0; clang diagnostic pop :: memcpy(fData.getAlias
(), other.fData.getAlias(), sizeof(decNumber)); } while (false
)
;
115 uprv_memcpy(fData.getArrayStart(),do { clang diagnostic push clang diagnostic ignored "-Waddress"
(void)0; (void)0; clang diagnostic pop :: memcpy(fData.getArrayStart
(), other.fData.getArrayStart(), other.fData.getArrayLimit() -
other.fData.getArrayStart()); } while (false)
116 other.fData.getArrayStart(),do { clang diagnostic push clang diagnostic ignored "-Waddress"
(void)0; (void)0; clang diagnostic pop :: memcpy(fData.getArrayStart
(), other.fData.getArrayStart(), other.fData.getArrayLimit() -
other.fData.getArrayStart()); } while (false)
117 other.fData.getArrayLimit() - other.fData.getArrayStart())do { clang diagnostic push clang diagnostic ignored "-Waddress"
(void)0; (void)0; clang diagnostic pop :: memcpy(fData.getArrayStart
(), other.fData.getArrayStart(), other.fData.getArrayLimit() -
other.fData.getArrayStart()); } while (false)
;
118}
119
120void DecNum::setTo(StringPiece str, UErrorCode& status) {
121 // We need NUL-terminated for decNumber; CharString guarantees this, but not StringPiece.
122 CharString cstr(str, status);
123 if (U_FAILURE(status)) { return; }
124 _setTo(cstr.data(), str.length(), status);
125}
126
127void DecNum::setTo(const char* str, UErrorCode& status) {
128 _setTo(str, static_cast<int32_t>(uprv_strlen(str):: strlen(str)), status);
129}
130
131void DecNum::setTo(double d, UErrorCode& status) {
132 // Need to check for NaN and Infinity before going into DoubleToStringConverter
133 if (std::isnan(d) != 0 || std::isfinite(d) == 0) {
134 status = U_UNSUPPORTED_ERROR;
135 return;
136 }
137
138 // First convert from double to string, then string to DecNum.
139 // Allocate enough room for: all digits, "E-324", and NUL-terminator.
140 char buffer[DoubleToStringConverter::kBase10MaximalLength + 6];
141 bool sign; // unused; always positive
142 int32_t length;
143 int32_t point;
144 DoubleToStringConverter::DoubleToAscii(
145 d,
146 DoubleToStringConverter::DtoaMode::SHORTEST,
147 0,
148 buffer,
149 sizeof(buffer),
150 &sign,
151 &length,
152 &point
153 );
154
155 // Read initial result as a string.
156 _setTo(buffer, length, status);
157
158 // Set exponent and bitmask. Note that DoubleToStringConverter does not do negatives.
159 fData.getAlias()->exponent += point - length;
160 fData.getAlias()->bits |= static_cast<uint8_t>(std::signbit(d) ? DECNEG0x80 : 0);
161}
162
163void DecNum::_setTo(const char* str, int32_t maxDigits, UErrorCode& status) {
164 if (maxDigits > kDefaultDigits) {
165 fData.resize(maxDigits, 0);
166 fContext.digits = maxDigits;
167 } else {
168 fContext.digits = kDefaultDigits;
169 }
170
171 static_assert(DECDPUN1 == 1, "Assumes that DECDPUN is set to 1");
172 uprv_decNumberFromStringuprv_decNumberFromString_71(fData.getAlias(), str, &fContext);
173
174 // Check for invalid syntax and set the corresponding error code.
175 if ((fContext.status & DEC_Conversion_syntax0x00000001) != 0) {
176 status = U_DECIMAL_NUMBER_SYNTAX_ERROR;
177 return;
178 } else if (fContext.status != 0) {
179 // Not a syntax error, but some other error, like an exponent that is too large.
180 status = U_UNSUPPORTED_ERROR;
181 return;
182 }
183}
184
185void
186DecNum::setTo(const uint8_t* bcd, int32_t length, int32_t scale, bool isNegative, UErrorCode& status) {
187 if (length > kDefaultDigits) {
188 fData.resize(length, 0);
189 fContext.digits = length;
190 } else {
191 fContext.digits = kDefaultDigits;
192 }
193
194 // "digits is of type int32_t, and must have a value in the range 1 through 999,999,999."
195 if (length < 1 || length > 999999999) {
196 // Too large for decNumber
197 status = U_UNSUPPORTED_ERROR;
198 return;
199 }
200 // "The exponent field holds the exponent of the number. Its range is limited by the requirement that
201 // "the range of the adjusted exponent of the number be balanced and fit within a whole number of
202 // "decimal digits (in this implementation, be –999,999,999 through +999,999,999). The adjusted
203 // "exponent is the exponent that would result if the number were expressed with a single digit before
204 // "the decimal point, and is therefore given by exponent+digits-1."
205 if (scale > 999999999 - length + 1 || scale < -999999999 - length + 1) {
206 // Too large for decNumber
207 status = U_UNSUPPORTED_ERROR;
208 return;
209 }
210
211 fData.getAlias()->digits = length;
212 fData.getAlias()->exponent = scale;
213 fData.getAlias()->bits = static_cast<uint8_t>(isNegative ? DECNEG0x80 : 0);
214 uprv_decNumberSetBCDuprv_decNumberSetBCD_71(fData, bcd, static_cast<uint32_t>(length));
215 if (fContext.status != 0) {
216 // Some error occurred while constructing the decNumber.
217 status = U_INTERNAL_PROGRAM_ERROR;
218 }
219}
220
221void DecNum::normalize() {
222 uprv_decNumberReduceuprv_decNumberReduce_71(fData, fData, &fContext);
223}
224
225void DecNum::multiplyBy(const DecNum& rhs, UErrorCode& status) {
226 uprv_decNumberMultiplyuprv_decNumberMultiply_71(fData, fData, rhs.fData, &fContext);
227 if (fContext.status != 0) {
228 status = U_INTERNAL_PROGRAM_ERROR;
229 }
230}
231
232void DecNum::divideBy(const DecNum& rhs, UErrorCode& status) {
233 uprv_decNumberDivideuprv_decNumberDivide_71(fData, fData, rhs.fData, &fContext);
234 if ((fContext.status & DEC_Inexact0x00000020) != 0) {
235 // Ignore.
236 } else if (fContext.status != 0) {
237 status = U_INTERNAL_PROGRAM_ERROR;
238 }
239}
240
241bool DecNum::isNegative() const {
242 return decNumberIsNegative(fData.getAlias())(((fData.getAlias())->bits&0x80)!=0);
243}
244
245bool DecNum::isZero() const {
246 return decNumberIsZero(fData.getAlias())(*(fData.getAlias())->lsu==0 && (fData.getAlias())
->digits==1 && (((fData.getAlias())->bits&(
0x40|0x20|0x10))==0))
;
247}
248
249bool DecNum::isSpecial() const {
250 return decNumberIsSpecial(fData.getAlias())(((fData.getAlias())->bits&(0x40|0x20|0x10))!=0);
251}
252
253bool DecNum::isInfinity() const {
254 return decNumberIsInfinite(fData.getAlias())(((fData.getAlias())->bits&0x40)!=0);
255}
256
257bool DecNum::isNaN() const {
258 return decNumberIsNaN(fData.getAlias())(((fData.getAlias())->bits&(0x20|0x10))!=0);
259}
260
261void DecNum::toString(ByteSink& output, UErrorCode& status) const {
262 if (U_FAILURE(status)) {
263 return;
264 }
265 // "string must be at least dn->digits+14 characters long"
266 int32_t minCapacity = fData.getAlias()->digits + 14;
267 MaybeStackArray<char, 30> buffer(minCapacity, status);
268 if (U_FAILURE(status)) {
269 return;
270 }
271 uprv_decNumberToStringuprv_decNumberToString_71(fData, buffer.getAlias());
272 output.Append(buffer.getAlias(), static_cast<int32_t>(uprv_strlen(buffer.getAlias()):: strlen(buffer.getAlias())));
273}
274
275#endif /* #if !UCONFIG_NO_FORMATTING */