mirror of
https://github.com/Z3Prover/z3
synced 2026-06-19 07:06:28 +00:00
Merge branch 'master' into goal2sat-skip-single-ref-cache
This commit is contained in:
commit
f4cdcce434
17 changed files with 213 additions and 72 deletions
94
.github/workflows/nightly-validation.yml
vendored
94
.github/workflows/nightly-validation.yml
vendored
|
|
@ -844,3 +844,97 @@ jobs:
|
|||
|
||||
- name: Run build script unit tests
|
||||
run: python -m unittest discover -s scripts/tests -p "test_*.py" -v
|
||||
|
||||
# ============================================================================
|
||||
# DOTNET MANAGED WRAPPER ARCHITECTURE VALIDATION
|
||||
# ============================================================================
|
||||
|
||||
validate-dotnet-anycpu:
|
||||
name: "Validate Microsoft.Z3.dll is AnyCPU (issue #9863)"
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6.0.3
|
||||
|
||||
- name: Download NuGet package from release
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
TAG="${{ github.event.inputs.release_tag }}"
|
||||
if [ -z "$TAG" ]; then
|
||||
TAG="Nightly"
|
||||
fi
|
||||
gh release download $TAG --pattern "*.nupkg" --dir nuget-packages
|
||||
|
||||
- name: Extract managed DLL from NuGet package
|
||||
run: |
|
||||
# NuGet packages are ZIP archives; exclude the symbols package
|
||||
NUPKG=$(ls nuget-packages/*.nupkg | grep -v '\.symbols\.' | grep -v '\.snupkg' | head -n 1)
|
||||
echo "Checking package: $NUPKG"
|
||||
unzip -q "$NUPKG" "lib/netstandard2.0/Microsoft.Z3.dll" -d nupkg-extracted
|
||||
|
||||
- name: Check PE Machine field is AnyCPU (not architecture-specific)
|
||||
run: |
|
||||
python3 - <<'EOF'
|
||||
import struct
|
||||
import sys
|
||||
|
||||
dll_path = "nupkg-extracted/lib/netstandard2.0/Microsoft.Z3.dll"
|
||||
|
||||
with open(dll_path, 'rb') as f:
|
||||
# Verify MZ magic
|
||||
if f.read(2) != b'MZ':
|
||||
print("ERROR: Not a valid PE file (missing MZ header)")
|
||||
sys.exit(1)
|
||||
|
||||
# Read PE header offset stored at 0x3C in the DOS stub
|
||||
f.seek(0x3C)
|
||||
pe_offset = struct.unpack('<I', f.read(4))[0]
|
||||
|
||||
# Verify PE signature
|
||||
f.seek(pe_offset)
|
||||
if f.read(4) != b'PE\x00\x00':
|
||||
print("ERROR: Missing PE\\0\\0 signature")
|
||||
sys.exit(1)
|
||||
|
||||
# COFF Machine field is the 2 bytes immediately after the PE signature
|
||||
machine = struct.unpack('<H', f.read(2))[0]
|
||||
|
||||
machine_names = {
|
||||
0x0000: "Unknown/AnyCPU",
|
||||
0x014C: "i386 (AnyCPU for managed assemblies)",
|
||||
0x8664: "AMD64/x64",
|
||||
0xAA64: "ARM64",
|
||||
0x01C0: "ARM",
|
||||
0x01C4: "ARM Thumb-2",
|
||||
}
|
||||
machine_name = machine_names.get(machine, f"0x{machine:04X}")
|
||||
print(f"Machine field: 0x{machine:04X} = {machine_name}")
|
||||
|
||||
if machine == 0x8664:
|
||||
print()
|
||||
print("FAIL: Machine is AMD64 (0x8664).")
|
||||
print("This prevents loading on arm64 .NET hosts even though the assembly")
|
||||
print("contains only pure IL (CorFlags.ILONLY=True).")
|
||||
print("The DLL must be built as AnyCPU (Machine=0x014C) so the CLR loader")
|
||||
print("accepts it on every host architecture.")
|
||||
print("See issue #9863 for details.")
|
||||
sys.exit(1)
|
||||
elif machine == 0xAA64:
|
||||
print()
|
||||
print("FAIL: Machine is ARM64 (0xAA64).")
|
||||
print("This prevents loading on x64 .NET hosts.")
|
||||
print("The DLL must be built as AnyCPU (Machine=0x014C).")
|
||||
sys.exit(1)
|
||||
elif machine in (0x014C, 0x0000):
|
||||
print()
|
||||
print("PASS: Machine field indicates AnyCPU.")
|
||||
print("Microsoft.Z3.dll will load on any .NET host architecture.")
|
||||
else:
|
||||
print()
|
||||
print(f"FAIL: Unexpected Machine field 0x{machine:04X}.")
|
||||
print("Expected 0x014C (i386/AnyCPU) for a managed-only assembly.")
|
||||
sys.exit(1)
|
||||
EOF
|
||||
|
|
|
|||
17
BUILD.bazel
17
BUILD.bazel
|
|
@ -19,14 +19,23 @@ filegroup(
|
|||
cmake(
|
||||
name = "z3_dynamic",
|
||||
generate_args = [
|
||||
"-G Ninja",
|
||||
"-G Ninja",
|
||||
"-D Z3_EXPORTED_TARGETS=", # prevents installation, leaving symlinks between dylibs intact on copy
|
||||
],
|
||||
lib_source = ":all_files",
|
||||
out_binaries = ["z3"],
|
||||
out_shared_libs = select({
|
||||
"@platforms//os:linux": ["libz3.so"],
|
||||
# "@platforms//os:osx": ["libz3.dylib"], # FIXME: this is not working, libz3<version>.dylib is not copied
|
||||
# NOTE: These will need to be manually bumped along side the version in MODULE.bazel/VERSION.txt/CMake
|
||||
"@platforms//os:linux": [
|
||||
"libz3.so",
|
||||
"libz3.so.4.17",
|
||||
"libz3.so.4.17.0.0",
|
||||
],
|
||||
"@platforms//os:osx": [
|
||||
"libz3.dylib",
|
||||
"libz3.4.17.dylib",
|
||||
"libz3.4.17.0.0.dylib",
|
||||
],
|
||||
"@platforms//os:windows": ["libz3.dll"],
|
||||
"//conditions:default": ["@platforms//:incompatible"],
|
||||
}),
|
||||
|
|
@ -36,7 +45,7 @@ cmake(
|
|||
cmake(
|
||||
name = "z3_static",
|
||||
generate_args = [
|
||||
"-G Ninja",
|
||||
"-G Ninja",
|
||||
"-D BUILD_SHARED_LIBS=OFF",
|
||||
"-D Z3_BUILD_LIBZ3_SHARED=OFF",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1804,6 +1804,7 @@ class DotNetDLLComponent(Component):
|
|||
<Description>Z3 is a satisfiability modulo theories solver from Microsoft Research.</Description>
|
||||
<Copyright>Copyright Microsoft Corporation. All rights reserved.</Copyright>
|
||||
<PackageTags>smt constraint solver theorem prover</PackageTags>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
%s
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
<Warn>4</Warn>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<DocumentationFile>$(OutputPath)\Microsoft.Z3.xml</DocumentationFile>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Compilation items -->
|
||||
|
|
|
|||
34
src/api/js/package-lock.json
generated
34
src/api/js/package-lock.json
generated
|
|
@ -5400,10 +5400,20 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.1.tgz",
|
||||
"integrity": "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/puzrin"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/markdown-it"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"uc.micro": "^2.0.0"
|
||||
|
|
@ -5501,15 +5511,25 @@
|
|||
}
|
||||
},
|
||||
"node_modules/markdown-it": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
|
||||
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
|
||||
"version": "14.2.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.2.0.tgz",
|
||||
"integrity": "sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/puzrin"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/markdown-it"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
"entities": "^4.4.0",
|
||||
"linkify-it": "^5.0.0",
|
||||
"linkify-it": "^5.0.1",
|
||||
"mdurl": "^2.0.0",
|
||||
"punycode.js": "^2.3.1",
|
||||
"uc.micro": "^2.1.0"
|
||||
|
|
|
|||
|
|
@ -768,7 +768,7 @@ void bit_blaster_tpl<Cfg>::mk_smod(unsigned sz, expr * const * a_bits, expr * co
|
|||
template<typename Cfg>
|
||||
void bit_blaster_tpl<Cfg>::mk_eq(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref & out) {
|
||||
expr_ref_vector out_bits(m());
|
||||
out_bits.reserve(sz);
|
||||
out_bits.resize(sz);
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
mk_iff(a_bits[i], b_bits[i], out);
|
||||
out_bits[i] = out;
|
||||
|
|
|
|||
|
|
@ -86,9 +86,15 @@ namespace seq {
|
|||
}
|
||||
|
||||
/*
|
||||
Collect the leaves of a t-regex der (an ITE / antimirov union /
|
||||
union-tree with regex leaves) into the output vector. Empty
|
||||
(re.empty) leaves are dropped.
|
||||
Collect the leaves of a t-regex der (an ITE-tree whose leaves are
|
||||
regex expressions) into the output vector. Empty (re.empty) leaves
|
||||
are dropped.
|
||||
|
||||
Each leaf is treated as a single bisimulation state regardless of
|
||||
its top-level shape (including re.union and re.antimirov_union):
|
||||
descending into a union at the leaf would split one state into
|
||||
several, which is semantically unsound for the bisimulation /
|
||||
union-find merging that follows.
|
||||
|
||||
Returns false if we encountered an unexpected node (e.g. a free
|
||||
variable creeping in) — in that case the caller should bail out.
|
||||
|
|
@ -102,9 +108,7 @@ namespace seq {
|
|||
expr* e = work.back();
|
||||
work.pop_back();
|
||||
expr* c = nullptr, * t = nullptr, * f = nullptr;
|
||||
if (m.is_ite(e, c, t, f) ||
|
||||
m_util.re.is_union(e, t, f) ||
|
||||
m_util.re.is_antimirov_union(e, t, f)) {
|
||||
if (m.is_ite(e, c, t, f)) {
|
||||
if (seen.insert_if_not_there(t))
|
||||
work.push_back(t);
|
||||
if (seen.insert_if_not_there(f))
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ Author:
|
|||
class dependent_expr_state {
|
||||
unsigned m_qhead = 0;
|
||||
bool m_suffix_frozen = false;
|
||||
unsigned m_num_recfun = 0, m_num_lambdas = 0;
|
||||
unsigned m_num_recfun = 0;
|
||||
lbool m_has_quantifiers = l_undef;
|
||||
ast_mark m_frozen;
|
||||
func_decl_ref_vector m_frozen_trail;
|
||||
|
|
|
|||
|
|
@ -4672,7 +4672,6 @@ namespace smt {
|
|||
theory_id th_id = l->get_id();
|
||||
|
||||
for (enode * parent : enode::parents(n)) {
|
||||
auto p = parent->get_expr();
|
||||
family_id fid = parent->get_family_id();
|
||||
if (fid != th_id && fid != m.get_basic_family_id()) {
|
||||
if (is_beta_redex(parent, n))
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ namespace smt {
|
|||
unsigned m_final_check_ls_steps = 30000;
|
||||
unsigned m_final_check_ls_steps_delta = 10000;
|
||||
unsigned m_final_check_ls_steps_min = 10000;
|
||||
unsigned m_final_check_ls_steps_max = 30000;
|
||||
bool m_has_unassigned_clause_after_resolve = false;
|
||||
unsigned m_after_resolve_decide_gap = 4;
|
||||
unsigned m_after_resolve_decide_count = 0;
|
||||
|
|
|
|||
|
|
@ -460,7 +460,6 @@ class parallel_solver {
|
|||
};
|
||||
|
||||
unsigned id;
|
||||
parallel_solver& p;
|
||||
batch_manager& b;
|
||||
ast_manager m; /* worker-local manager */
|
||||
ref<solver> s; /* translated solver copy */
|
||||
|
|
@ -579,7 +578,7 @@ class parallel_solver {
|
|||
worker(unsigned id, parallel_solver& p,
|
||||
solver& src, params_ref const& params,
|
||||
expr_ref_vector const& src_asms)
|
||||
: id(id), p(p), b(p.m_batch_manager),
|
||||
: id(id), b(p.m_batch_manager),
|
||||
asms(m), m_g2l(src.get_manager(), m), m_l2g(m, src.get_manager())
|
||||
{
|
||||
/* create translated solver copy */
|
||||
|
|
|
|||
|
|
@ -185,6 +185,10 @@ public:
|
|||
expr_safe_replace rep(m);
|
||||
|
||||
tactic_report report("lia2card", *g);
|
||||
if (recfun::util(m()).has_rec_defs()) {
|
||||
result.push_back(g.get());
|
||||
return;
|
||||
}
|
||||
|
||||
bound_manager bounds(m);
|
||||
for (unsigned i = 0; i < g->size(); ++i)
|
||||
|
|
|
|||
|
|
@ -452,7 +452,7 @@ static void project(nlsat::solver& s, nlsat::explain& ex, nlsat::var x, unsigned
|
|||
std::cout << "\n";
|
||||
}
|
||||
|
||||
static void project_fa(nlsat::solver& s, nlsat::explain& ex, nlsat::var x, unsigned num, nlsat::literal const* lits) {
|
||||
static nlsat::scoped_literal_vector project_fa(nlsat::solver& s, nlsat::explain& ex, nlsat::var x, unsigned num, nlsat::literal const* lits) {
|
||||
std::cout << "Project ";
|
||||
nlsat::scoped_literal_vector result(s);
|
||||
ex.compute_conflict_explanation(num, lits, result);
|
||||
|
|
@ -464,6 +464,7 @@ static void project_fa(nlsat::solver& s, nlsat::explain& ex, nlsat::var x, unsig
|
|||
s.display(std::cout << " ", ~lits[i]);
|
||||
}
|
||||
std::cout << ")\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
static nlsat::literal mk_gt(nlsat::solver& s, nlsat::poly* p) {
|
||||
|
|
@ -490,6 +491,39 @@ static nlsat::literal mk_root_eq(nlsat::solver& s, nlsat::poly* p, nlsat::var x,
|
|||
return nlsat::literal(b, false);
|
||||
}
|
||||
|
||||
static bool contains_var(nlsat::var_vector const& vars, nlsat::var x) {
|
||||
for (auto v : vars) {
|
||||
if (v == x)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool clause_contains_root_dependency(
|
||||
nlsat::solver& s,
|
||||
nlsat::scoped_literal_vector const& result,
|
||||
nlsat::atom::kind kind,
|
||||
nlsat::var target,
|
||||
unsigned root_index,
|
||||
nlsat::var dep1,
|
||||
nlsat::var dep2,
|
||||
nlsat::var dep3) {
|
||||
nlsat::pmanager& pm = s.pm();
|
||||
nlsat::var_vector vars;
|
||||
for (auto l : result) {
|
||||
nlsat::atom* a = s.bool_var2atom(l.var());
|
||||
if (!a || !a->is_root_atom() || a->get_kind() != kind)
|
||||
continue;
|
||||
nlsat::root_atom* ra = nlsat::to_root_atom(a);
|
||||
if (ra->x() != target || ra->i() != root_index || pm.max_var(ra->p()) != target)
|
||||
continue;
|
||||
s.vars(l, vars);
|
||||
if (contains_var(vars, dep1) && contains_var(vars, dep2) && contains_var(vars, dep3))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void set_assignment_value(nlsat::assignment& as, anum_manager& am, nlsat::var v, rational const& val) {
|
||||
scoped_anum tmp(am);
|
||||
am.set(tmp, val.to_mpq());
|
||||
|
|
@ -1183,8 +1217,8 @@ static void tst_15() {
|
|||
auto cell = lws.single_cell();
|
||||
}
|
||||
|
||||
// Test case for unsound lemma lws2380 - comparing standard projection vs levelwise
|
||||
// The issue: x7 is unconstrained in levelwise output but affects the section polynomial
|
||||
// Historical lws2380 regression test: both projection paths should preserve
|
||||
// the x7-linked section/root constraints that witness the projected dependency.
|
||||
static void tst_16() {
|
||||
// enable_trace("nlsat_explain");
|
||||
|
||||
|
|
@ -1283,8 +1317,9 @@ static void tst_16() {
|
|||
lits.push_back(mk_gt(s, p0.get())); // x13 > 0
|
||||
lits.push_back(mk_gt(s, p1.get())); // p1 > 0
|
||||
|
||||
project_fa(s, ex, x13, lits.size(), lits.data());
|
||||
auto result = project_fa(s, ex, x13, lits.size(), lits.data());
|
||||
std::cout << "\n";
|
||||
ENSURE(clause_contains_root_dependency(s, result, nlsat::atom::ROOT_EQ, x11, 1, x7, x8, x10));
|
||||
};
|
||||
|
||||
run_test(false); // Standard projection
|
||||
|
|
@ -2144,11 +2179,11 @@ static void tst_22() {
|
|||
}
|
||||
}
|
||||
|
||||
if (all_false) {
|
||||
if (all_false)
|
||||
std::cout << "*** ALL literals FALSE at counterexample - LEMMA IS UNSOUND! ***\n";
|
||||
} else {
|
||||
else
|
||||
std::cout << "At least one literal is TRUE - lemma is sound at this point\n";
|
||||
}
|
||||
ENSURE(!all_false);
|
||||
};
|
||||
|
||||
run_test(false); // lws=false (buggy)
|
||||
|
|
|
|||
|
|
@ -62,10 +62,6 @@ public:
|
|||
struct key_data {
|
||||
Key * m_key = nullptr;
|
||||
Value m_value;
|
||||
key_data() = default;
|
||||
key_data(Key* k): m_key(k) {}
|
||||
key_data(Key* k, Value const& v): m_key(k), m_value(v) {}
|
||||
key_data(Key* k, Value&& v): m_key(k), m_value(std::move(v)) {}
|
||||
Value const & get_value() const { return m_value; }
|
||||
Key & get_key () const { return *m_key; }
|
||||
unsigned hash() const { return m_key->hash(); }
|
||||
|
|
@ -136,15 +132,15 @@ public:
|
|||
}
|
||||
|
||||
void insert(Key * const k, Value const & v) {
|
||||
m_table.insert(key_data(k, v));
|
||||
m_table.insert(key_data{k, v});
|
||||
}
|
||||
|
||||
void insert(Key * const k, Value && v) {
|
||||
m_table.insert(key_data(k, std::move(v)));
|
||||
m_table.insert(key_data{k, std::move(v)});
|
||||
}
|
||||
|
||||
Value& insert_if_not_there(Key * k, Value const & v) {
|
||||
return m_table.insert_if_not_there2(key_data(k, v))->get_data().m_value;
|
||||
return m_table.insert_if_not_there2(key_data{k, v})->get_data().m_value;
|
||||
}
|
||||
|
||||
Value& insert_if_not_there(Key * k, Value && v) {
|
||||
|
|
@ -194,7 +190,7 @@ public:
|
|||
}
|
||||
|
||||
iterator find_iterator(Key * k) const {
|
||||
return m_table.find(key_data(k));
|
||||
return m_table.find(key_data{k});
|
||||
}
|
||||
|
||||
bool contains(Key * k) const {
|
||||
|
|
@ -202,7 +198,7 @@ public:
|
|||
}
|
||||
|
||||
void remove(Key * k) {
|
||||
m_table.remove(key_data(k));
|
||||
m_table.remove(key_data{k});
|
||||
}
|
||||
|
||||
void erase(Key * k) {
|
||||
|
|
@ -213,7 +209,7 @@ public:
|
|||
|
||||
void get_collisions(Key * k, vector<Key*>& collisions) {
|
||||
vector<key_data> cs;
|
||||
m_table.get_collisions(key_data(k), cs);
|
||||
m_table.get_collisions(key_data{k}, cs);
|
||||
for (key_data const& kd : cs) {
|
||||
collisions.push_back(kd.m_key);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,17 +59,13 @@ protected:
|
|||
class entry;
|
||||
public:
|
||||
class key_data {
|
||||
Key1 * m_key1;
|
||||
Key2 * m_key2;
|
||||
Key1 * m_key1 = nullptr;
|
||||
Key2 * m_key2 = nullptr;
|
||||
Value m_value;
|
||||
unsigned m_hash;
|
||||
unsigned m_hash = 0;
|
||||
friend class entry;
|
||||
public:
|
||||
key_data():
|
||||
m_key1(nullptr),
|
||||
m_key2(nullptr),
|
||||
m_hash(0) {
|
||||
}
|
||||
key_data() = default;
|
||||
key_data(Key1 * k1, Key2 * k2):
|
||||
m_key1(k1),
|
||||
m_key2(k2) {
|
||||
|
|
|
|||
|
|
@ -60,19 +60,14 @@ protected:
|
|||
class entry;
|
||||
public:
|
||||
class key_data {
|
||||
Key1 * m_key1;
|
||||
Key2 * m_key2;
|
||||
Key3 * m_key3;
|
||||
Key1 * m_key1 = nullptr;
|
||||
Key2 * m_key2 = nullptr;
|
||||
Key3 * m_key3 = nullptr;
|
||||
Value m_value;
|
||||
unsigned m_hash;
|
||||
unsigned m_hash = 0;
|
||||
friend class entry;
|
||||
public:
|
||||
key_data():
|
||||
m_key1(nullptr),
|
||||
m_key2(nullptr),
|
||||
m_key3(nullptr),
|
||||
m_hash(0) {
|
||||
}
|
||||
key_data() = default;
|
||||
key_data(Key1 * k1, Key2 * k2, Key3 * k3):
|
||||
m_key1(k1),
|
||||
m_key2(k2),
|
||||
|
|
|
|||
|
|
@ -30,17 +30,6 @@ class symbol_table {
|
|||
struct key_data {
|
||||
symbol m_key;
|
||||
T m_data;
|
||||
|
||||
key_data() = default;
|
||||
|
||||
explicit key_data(symbol k):
|
||||
m_key(k) {
|
||||
}
|
||||
|
||||
key_data(symbol k, const T & d):
|
||||
m_key(k),
|
||||
m_data(d) {
|
||||
}
|
||||
};
|
||||
|
||||
struct key_data_hash_proc {
|
||||
|
|
@ -129,7 +118,7 @@ public:
|
|||
}
|
||||
|
||||
bool contains(symbol key) const {
|
||||
return m_sym_table.contains(key_data(key));
|
||||
return m_sym_table.contains(key_data{key});
|
||||
}
|
||||
|
||||
unsigned get_scope_level() const {
|
||||
|
|
@ -148,11 +137,11 @@ public:
|
|||
m_trail_stack.push_back(dummy);
|
||||
key_data & new_entry = m_trail_stack.back();
|
||||
new_entry.m_key = symbol::mark(new_entry.m_key);
|
||||
m_sym_table.insert(key_data(key, data));
|
||||
m_sym_table.insert(key_data{key, data});
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_sym_table.insert(key_data(key, data));
|
||||
m_sym_table.insert(key_data{key, data});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue