| 2401 | } |
| 2402 | |
| 2403 | void Memory::memset(const expr &p, const StateValue &val, const expr &bytesize, |
| 2404 | uint64_t align, const set<expr> &undef_vars, |
| 2405 | bool deref_check) { |
| 2406 | assert(!memory_unused()); |
| 2407 | assert(!val.isValid() || val.bits() == 8); |
| 2408 | unsigned bytesz = bits_byte / 8; |
| 2409 | Pointer ptr(*this, p); |
| 2410 | if (deref_check) |
| 2411 | state->addUB(ptr.isDereferenceable(bytesize, align, true, false, false)); |
| 2412 | |
| 2413 | auto wval = val; |
| 2414 | for (unsigned i = 1; i < bytesz; ++i) { |
| 2415 | wval = wval.concat(val); |
| 2416 | } |
| 2417 | assert(!val.isValid() || wval.bits() == bits_byte); |
| 2418 | |
| 2419 | auto bytes = valueToBytes(wval, IntType("", bits_byte), *this, *state); |
| 2420 | assert(bytes.size() == 1); |
| 2421 | expr raw_byte = std::move(bytes[0])(); |
| 2422 | |
| 2423 | uint64_t n; |
| 2424 | if (bytesize.isUInt(n) && (n / bytesz) <= 4) { |
| 2425 | vector<pair<unsigned, expr>> to_store; |
| 2426 | for (unsigned i = 0; i < n; i += bytesz) { |
| 2427 | to_store.emplace_back(i, raw_byte); |
| 2428 | } |
| 2429 | store(ptr, to_store, undef_vars, align); |
| 2430 | } else { |
| 2431 | expr offset = expr::mkQVar(0, Pointer::bitsShortOffset()); |
| 2432 | storeLambda(ptr, offset, bytesize, {{0, raw_byte}}, undef_vars, align); |
| 2433 | } |
| 2434 | } |
| 2435 | |
| 2436 | void Memory::memset_pattern(const expr &ptr0, const expr &pattern0, |
| 2437 | const expr &bytesize, unsigned pattern_length) { |
no test coverage detected