summaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-10-11 23:49:51 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-10-11 23:49:51 -0700
commit35f3649a02f7edd0f69d3e1dcbed7fc2c435ce9f (patch)
tree8c78ce4d12ce91ad4c60577009634c04f862f8be /hash.c
parente3ef5c56c8445b409ccb342c78aa79e7c2616582 (diff)
downloadtxr-35f3649a02f7edd0f69d3e1dcbed7fc2c435ce9f.tar.gz
txr-35f3649a02f7edd0f69d3e1dcbed7fc2c435ce9f.tar.bz2
txr-35f3649a02f7edd0f69d3e1dcbed7fc2c435ce9f.zip
hash: strengthen type mutual exclusion check.
* hash.c (equal_based_p): Take additional argument eq indicating that :eq-based has been specified. Check all three exclusive combinations. (hashv): Call equal_based_p unconditionally, even when :eq-based is specified and we don't use this function's return value so we benefit from that function's exclusion check. Pass the eq boolean, as required.
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/hash.c b/hash.c
index f7cd794a..83e73e35 100644
--- a/hash.c
+++ b/hash.c
@@ -1267,15 +1267,21 @@ void hash_process_weak(void)
do_iters();
}
-static val equal_based_p(val equal, val eql, val wkeys)
+static val equal_based_p(val equal, val eql, val eq, val wkeys)
{
+ val mutex = lit("make-hash: mutually exclusive ~s and ~s");
+
if (opt_compat && opt_compat <= 187)
return equal;
if (equal && eql)
- uw_throwf(error_s,
- lit("make-hash: mutually exclusive :equal-based and :eql-based"),
- nao);
+ uw_throwf(error_s, mutex, equal_based_k, eql_based_k, nao);
+
+ if (equal && eq)
+ uw_throwf(error_s, mutex, equal_based_k, eq_based_k, nao);
+
+ if (eql && eq)
+ uw_throwf(error_s, mutex, eql_based_k, eq_based_k, nao);
if (wkeys) {
if (equal)
@@ -1301,10 +1307,9 @@ val hashv(struct args *args)
{ eq_based_k, nil, &eq },
{ userdata_k, t, &userdata }
};
- val hash = (args_keys_extract(args, akv, sizeof akv / sizeof akv[0]),
- if3(eq,
- make_eq_hash(wkeys, wvals),
- make_hash(wkeys, wvals, equal_based_p(equal, eql, wkeys))));
+ val ebp = (args_keys_extract(args, akv, sizeof akv / sizeof akv[0]),
+ equal_based_p(equal, eql, eq, wkeys));
+ val hash = if3(eq, make_eq_hash(wkeys, wvals), make_hash(wkeys, wvals, ebp));
if (userdata)
set_hash_userdata(hash, userdata);
return hash;