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 fromstring.cc -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 -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D V8_GYP_BUILD -D V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D V8_TARGET_ARCH_X64 -D V8_HAVE_TARGET_OS -D V8_TARGET_OS_LINUX -D V8_EMBEDDER_STRING="-node.8" -D ENABLE_DISASSEMBLER -D V8_PROMISE_INTERNAL_FIELD_COUNT=1 -D V8_SHORT_BUILTIN_CALLS -D OBJECT_PRINT -D V8_INTL_SUPPORT -D V8_ATOMIC_OBJECT_FIELD_WRITES -D V8_ENABLE_LAZY_SOURCE_POSITIONS -D V8_USE_SIPHASH -D V8_SHARED_RO_HEAP -D V8_WIN64_UNWINDING_INFO -D V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH -D V8_SNAPSHOT_COMPRESSION -D V8_ENABLE_WEBASSEMBLY -D V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS -D V8_ALLOCATION_FOLDING -D V8_ALLOCATION_SITE_TRACKING -D V8_SCRIPTORMODULE_LEGACY_LIFETIME -D V8_ADVANCED_BIGINT_ALGORITHMS -D ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC -D UCONFIG_NO_SERVICE=1 -D U_ENABLE_DYLOAD=0 -D U_STATIC_IMPLEMENTATION=1 -D U_HAVE_STD_STRING=1 -D UCONFIG_NO_BREAK_ITERATION=0 -I ../deps/v8 -I ../deps/v8/include -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/inspector-generated-output-root -I ../deps/v8/third_party/inspector_protocol -I /home/maurizio/node-v18.6.0/out/Release/obj/gen -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/generate-bytecode-output-root -I ../deps/icu-small/source/i18n -I ../deps/icu-small/source/common -I ../deps/v8/third_party/zlib -I ../deps/v8/third_party/zlib/google -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-return-type -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fno-rtti -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/v8/src/bigint/fromstring.cc
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | #include "src/bigint/bigint-internal.h" |
| 6 | #include "src/bigint/vector-arithmetic.h" |
| 7 | |
| 8 | namespace v8 { |
| 9 | namespace bigint { |
| 10 | |
| 11 | |
| 12 | |
| 13 | void ProcessorImpl::FromStringClassic(RWDigits Z, |
| 14 | FromStringAccumulator* accumulator) { |
| 15 | |
| 16 | DCHECK(accumulator->stack_parts_used_ > 0); |
| 17 | Z[0] = accumulator->stack_parts_[0]; |
| 18 | RWDigits already_set(Z, 0, 1); |
| 19 | for (int i = 1; i < Z.len(); i++) Z[i] = 0; |
| 20 | |
| 21 | |
| 22 | |
| 23 | int num_stack_parts = accumulator->stack_parts_used_; |
| 24 | if (num_stack_parts == 1) return; |
| 25 | const std::vector<digit_t>& heap_parts = accumulator->heap_parts_; |
| 26 | int num_heap_parts = static_cast<int>(heap_parts.size()); |
| 27 | |
| 28 | const digit_t max_multiplier = accumulator->max_multiplier_; |
| 29 | |
| 30 | if (num_heap_parts == 0) { |
| 31 | for (int i = 1; i < num_stack_parts - 1; i++) { |
| 32 | MultiplySingle(Z, already_set, max_multiplier); |
| 33 | Add(Z, accumulator->stack_parts_[i]); |
| 34 | already_set.set_len(already_set.len() + 1); |
| 35 | } |
| 36 | MultiplySingle(Z, already_set, accumulator->last_multiplier_); |
| 37 | Add(Z, accumulator->stack_parts_[num_stack_parts - 1]); |
| 38 | return; |
| 39 | } |
| 40 | |
| 41 | for (int i = 1; i < num_heap_parts - 1; i++) { |
| 42 | MultiplySingle(Z, already_set, max_multiplier); |
| 43 | Add(Z, accumulator->heap_parts_[i]); |
| 44 | already_set.set_len(already_set.len() + 1); |
| 45 | } |
| 46 | MultiplySingle(Z, already_set, accumulator->last_multiplier_); |
| 47 | Add(Z, accumulator->heap_parts_.back()); |
| 48 | } |
| 49 | |
| 50 | |
| 51 | |
| 52 | |
| 53 | |
| 54 | |
| 55 | |
| 56 | |
| 57 | |
| 58 | |
| 59 | |
| 60 | |
| 61 | |
| 62 | |
| 63 | |
| 64 | |
| 65 | |
| 66 | |
| 67 | |
| 68 | |
| 69 | |
| 70 | |
| 71 | |
| 72 | |
| 73 | |
| 74 | |
| 75 | |
| 76 | |
| 77 | |
| 78 | |
| 79 | |
| 80 | |
| 81 | |
| 82 | |
| 83 | |
| 84 | |
| 85 | |
| 86 | |
| 87 | |
| 88 | |
| 89 | void ProcessorImpl::FromStringLarge(RWDigits Z, |
| 90 | FromStringAccumulator* accumulator) { |
| 91 | int num_parts = static_cast<int>(accumulator->heap_parts_.size()); |
| 92 | DCHECK(num_parts >= 2); |
| 93 | DCHECK(Z.len() >= num_parts); |
| 94 | RWDigits parts(accumulator->heap_parts_.data(), num_parts); |
| 95 | Storage multipliers_storage(num_parts); |
| 96 | RWDigits multipliers(multipliers_storage.get(), num_parts); |
| 97 | RWDigits temp(Z, 0, num_parts); |
| 98 | |
| 99 | |
| 100 | |
| 101 | { |
| 102 | digit_t max_multiplier = accumulator->max_multiplier_; |
| 103 | digit_t last_multiplier = accumulator->last_multiplier_; |
| 104 | RWDigits new_parts = temp; |
| 105 | RWDigits new_multipliers = parts; |
| 106 | int i = 0; |
| 107 | for (; i + 1 < num_parts; i += 2) { |
| 108 | digit_t p_in = parts[i]; |
| 109 | digit_t p_in2 = parts[i + 1]; |
| 110 | digit_t m_in = max_multiplier; |
| 111 | digit_t m_in2 = i == num_parts - 2 ? last_multiplier : max_multiplier; |
| 112 | |
| 113 | digit_t p_high; |
| 114 | digit_t p_low = digit_mul(p_in, m_in2, &p_high); |
| 115 | digit_t carry; |
| 116 | new_parts[i] = digit_add2(p_low, p_in2, &carry); |
| 117 | new_parts[i + 1] = p_high + carry; |
| 118 | |
| 119 | if (i > 0) { |
| 120 | if (i > 2 && m_in2 != last_multiplier) { |
| 121 | new_multipliers[i] = new_multipliers[i - 2]; |
| 122 | new_multipliers[i + 1] = new_multipliers[i - 1]; |
| 123 | } else { |
| 124 | digit_t m_high; |
| 125 | new_multipliers[i] = digit_mul(m_in, m_in2, &m_high); |
| 126 | new_multipliers[i + 1] = m_high; |
| 127 | } |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | if (i < num_parts) { |
| 132 | new_parts[i] = parts[i]; |
| 133 | new_multipliers[i] = last_multiplier; |
| 134 | i += 2; |
| 135 | } |
| 136 | num_parts = i >> 1; |
| 137 | RWDigits new_temp = multipliers; |
| 138 | parts = new_parts; |
| 139 | multipliers = new_multipliers; |
| 140 | temp = new_temp; |
| 141 | AddWorkEstimate(num_parts); |
| 142 | } |
| 143 | int part_len = 2; |
| 144 | |
| 145 | |
| 146 | while (num_parts > 1) { |
| 147 | RWDigits new_parts = temp; |
| 148 | RWDigits new_multipliers = parts; |
| 149 | int new_part_len = part_len * 2; |
| 150 | int i = 0; |
| 151 | for (; i + 1 < num_parts; i += 2) { |
| 152 | int start = i * part_len; |
| 153 | Digits p_in(parts, start, part_len); |
| 154 | Digits p_in2(parts, start + part_len, part_len); |
| 155 | Digits m_in(multipliers, start, part_len); |
| 156 | Digits m_in2(multipliers, start + part_len, part_len); |
| 157 | RWDigits p_out(new_parts, start, new_part_len); |
| 158 | RWDigits m_out(new_multipliers, start, new_part_len); |
| 159 | |
| 160 | Multiply(p_out, p_in, m_in2); |
| 161 | if (should_terminate()) return; |
| 162 | digit_t overflow = AddAndReturnOverflow(p_out, p_in2); |
| 163 | DCHECK(overflow == 0); |
| 164 | USE(overflow); |
| 165 | |
| 166 | if (i > 0) { |
| 167 | bool copied = false; |
| 168 | if (i > 2) { |
| 169 | int prev_start = (i - 2) * part_len; |
| 170 | Digits m_in_prev(multipliers, prev_start, part_len); |
| 171 | Digits m_in2_prev(multipliers, prev_start + part_len, part_len); |
| 172 | if (Compare(m_in, m_in_prev) == 0 && |
| 173 | Compare(m_in2, m_in2_prev) == 0) { |
| 174 | copied = true; |
| 175 | Digits m_out_prev(new_multipliers, prev_start, new_part_len); |
| 176 | for (int k = 0; k < new_part_len; k++) m_out[k] = m_out_prev[k]; |
| 177 | } |
| 178 | } |
| 179 | if (!copied) { |
| 180 | Multiply(m_out, m_in, m_in2); |
| 181 | if (should_terminate()) return; |
| 182 | } |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | if (i < num_parts) { |
| 187 | Digits p_in(parts, i * part_len, part_len); |
| 188 | Digits m_in(multipliers, i * part_len, part_len); |
| 189 | RWDigits p_out(new_parts, i * part_len, new_part_len); |
| 190 | RWDigits m_out(new_multipliers, i * part_len, new_part_len); |
| 191 | int k = 0; |
| 192 | for (; k < p_in.len(); k++) p_out[k] = p_in[k]; |
| 193 | for (; k < p_out.len(); k++) p_out[k] = 0; |
| 194 | k = 0; |
| 195 | for (; k < m_in.len(); k++) m_out[k] = m_in[k]; |
| 196 | for (; k < m_out.len(); k++) m_out[k] = 0; |
| 197 | i += 2; |
| 198 | } |
| 199 | num_parts = i >> 1; |
| 200 | part_len = new_part_len; |
| 201 | RWDigits new_temp = multipliers; |
| 202 | parts = new_parts; |
| 203 | multipliers = new_multipliers; |
| 204 | temp = new_temp; |
| 205 | } |
| 206 | |
| 207 | if (parts.digits() != Z.digits()) { |
| 208 | int i = 0; |
| 209 | for (; i < parts.len(); i++) Z[i] = parts[i]; |
| 210 | |
| 211 | for (; i < Z.len(); i++) Z[i] = 0; |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | |
| 216 | |
| 217 | |
| 218 | |
| 219 | |
| 220 | |
| 221 | |
| 222 | |
| 223 | |
| 224 | |
| 225 | |
| 226 | |
| 227 | |
| 228 | |
| 229 | |
| 230 | |
| 231 | |
| 232 | |
| 233 | |
| 234 | |
| 235 | |
| 236 | |
| 237 | |
| 238 | |
| 239 | |
| 240 | void ProcessorImpl::FromStringBasePowerOfTwo( |
| 241 | RWDigits Z, FromStringAccumulator* accumulator) { |
| 242 | const int num_parts = accumulator->ResultLength(); |
| 243 | DCHECK(num_parts >= 1); |
| 244 | DCHECK(Z.len() >= num_parts); |
| 245 | Digits parts(accumulator->heap_parts_.size() > 0 |
| 8 | | Assuming the condition is false | |
|
| |
| 246 | ? accumulator->heap_parts_.data() |
| 247 | : accumulator->stack_parts_, |
| 248 | num_parts); |
| 249 | uint8_t radix = accumulator->radix_; |
| 250 | DCHECK(radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32); |
| 251 | const int char_bits = BitLength(radix - 1); |
| |
| 12 | | Returning from 'BitLength' | |
|
| 13 | | 'char_bits' initialized to 0 | |
|
| 252 | const int unused_last_part_bits = |
| 253 | static_cast<int>(accumulator->last_multiplier_); |
| 254 | const int unused_part_bits = kDigitBits % char_bits; |
| |
| 255 | const int max_part_bits = kDigitBits - unused_part_bits; |
| 256 | int z_index = 0; |
| 257 | int part_index = num_parts - 1; |
| 258 | |
| 259 | |
| 260 | |
| 261 | if (unused_last_part_bits == 0) { |
| 262 | DCHECK(kDigitBits % char_bits == 0); |
| 263 | while (part_index >= 0) { |
| 264 | Z[z_index++] = parts[part_index--]; |
| 265 | } |
| 266 | for (; z_index < Z.len(); z_index++) Z[z_index] = 0; |
| 267 | return; |
| 268 | } |
| 269 | |
| 270 | |
| 271 | |
| 272 | digit_t digit = parts[part_index--]; |
| 273 | |
| 274 | int digit_bits = kDigitBits - unused_last_part_bits; |
| 275 | while (part_index >= 0) { |
| 276 | |
| 277 | digit_t part; |
| 278 | |
| 279 | int part_bits; |
| 280 | while (digit_bits < kDigitBits) { |
| 281 | part = parts[part_index--]; |
| 282 | part_bits = max_part_bits; |
| 283 | digit |= part << digit_bits; |
| 284 | int part_shift = kDigitBits - digit_bits; |
| 285 | if (part_shift > part_bits) { |
| 286 | digit_bits += part_bits; |
| 287 | part = 0; |
| 288 | part_bits = 0; |
| 289 | if (part_index < 0) break; |
| 290 | } else { |
| 291 | digit_bits = kDigitBits; |
| 292 | part >>= part_shift; |
| 293 | part_bits -= part_shift; |
| 294 | } |
| 295 | } |
| 296 | Z[z_index++] = digit; |
| 297 | digit = part; |
| 298 | digit_bits = part_bits; |
| 299 | } |
| 300 | if (digit_bits > 0) { |
| 301 | Z[z_index++] = digit; |
| 302 | } |
| 303 | for (; z_index < Z.len(); z_index++) Z[z_index] = 0; |
| 304 | } |
| 305 | |
| 306 | void ProcessorImpl::FromString(RWDigits Z, FromStringAccumulator* accumulator) { |
| 307 | if (accumulator->inline_everything_) { |
| 2 | | Assuming field 'inline_everything_' is false | |
|
| |
| 308 | int i = 0; |
| 309 | for (; i < accumulator->stack_parts_used_; i++) { |
| 310 | Z[i] = accumulator->stack_parts_[i]; |
| 311 | } |
| 312 | for (; i < Z.len(); i++) Z[i] = 0; |
| 313 | } else if (accumulator->stack_parts_used_ == 0) { |
| 4 | | Assuming field 'stack_parts_used_' is not equal to 0 | |
|
| |
| 314 | for (int i = 0; i < Z.len(); i++) Z[i] = 0; |
| 315 | } else if (IsPowerOfTwo(accumulator->radix_)) { |
| |
| 316 | FromStringBasePowerOfTwo(Z, accumulator); |
| 7 | | Calling 'ProcessorImpl::FromStringBasePowerOfTwo' | |
|
| 317 | } else if (accumulator->ResultLength() < kFromStringLargeThreshold) { |
| 318 | FromStringClassic(Z, accumulator); |
| 319 | } else { |
| 320 | FromStringLarge(Z, accumulator); |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | Status Processor::FromString(RWDigits Z, FromStringAccumulator* accumulator) { |
| 325 | ProcessorImpl* impl = static_cast<ProcessorImpl*>(this); |
| 326 | impl->FromString(Z, accumulator); |
| 1 | Calling 'ProcessorImpl::FromString' | |
|
| 327 | return impl->get_and_clear_status(); |
| 328 | } |
| 329 | |
| 330 | } |
| 331 | } |