summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--struct.c31
-rw-r--r--tests/012/oop-seq.tl14
2 files changed, 34 insertions, 11 deletions
diff --git a/struct.c b/struct.c
index 3bcdd29a..5e8c7647 100644
--- a/struct.c
+++ b/struct.c
@@ -332,6 +332,24 @@ static void static_slot_home_fixup(struct struct_type *st)
}
}
+static void invalidate_special_slot_nonexistence(struct struct_type *st)
+{
+ if (st->spslot != 0) {
+ int i;
+ for (i = 0; i < num_special_slots; i++) {
+ if (st->spslot[i] == coerce(struct stslot *, -1))
+ st->spslot[i] = 0;
+ }
+ }
+}
+
+static void invalidate_special_slots(struct struct_type *st)
+{
+ if (st->spslot != 0)
+ memset(st->spslot, 0, sizeof *st->spslot * num_special_slots);
+}
+
+
static val get_all_supers(val supers, val self)
{
list_collect_decl (all_supers, ptail);
@@ -572,6 +590,7 @@ val make_struct_type(val name, val supers,
st->nslots = sl;
st->nstslots = stsl;
static_slot_home_fixup(st);
+ invalidate_special_slots(st);
sethash(struct_type_hash, name, stype);
@@ -1304,17 +1323,6 @@ val static_slot(val stype, val sym)
no_such_static_slot(self, stype, sym);
}
-static void invalidate_special_slot_nonexistence(struct struct_type *st)
-{
- if (st->spslot != 0) {
- int i;
- for (i = 0; i < num_special_slots; i++) {
- if (st->spslot[i] == coerce(struct stslot *, -1))
- st->spslot[i] = 0;
- }
- }
-}
-
val static_slot_set(val stype, val sym, val newval)
{
val self = lit("static-slot-set");
@@ -1444,6 +1452,7 @@ static val static_slot_ens_rec(val stype, val sym, val newval,
sizeof *st->stslot,
coerce(mem_t *, &null_ptr)));
static_slot_home_fixup_rec(st);
+ invalidate_special_slots(st);
set(mkloc(st->slots, stype), append2(st->slots, cons(sym, nil)));
stsl = &st->stslot[st->nstslots];
diff --git a/tests/012/oop-seq.tl b/tests/012/oop-seq.tl
index 919f34cc..e91564fc 100644
--- a/tests/012/oop-seq.tl
+++ b/tests/012/oop-seq.tl
@@ -54,3 +54,17 @@
(test (list-seq (new counter-fast init 0 step 1 limit 0))
nil)
+
+;; The following reproduced a segfault when the change was made to allow del to
+;; work with structs that have lambda and lambda-set.
+
+(defstruct blah ()
+ (:method lambda-set (me . args)))
+
+(defparm o (new blah))
+
+(set [o 1..20] 42)
+
+(defmeth blah lambda (me . args))
+
+(set [o 1..20] 42)