diff options
Diffstat (limited to 'src/datatype.c')
-rw-r--r-- | src/datatype.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/datatype.c b/src/datatype.c index 002ed46a..dcda32c8 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -1099,6 +1099,7 @@ static struct datatype *dtype_alloc(void) dtype = xzalloc(sizeof(*dtype)); dtype->flags = DTYPE_F_ALLOC; + dtype->refcnt = 1; return dtype; } @@ -1116,12 +1117,19 @@ struct datatype *datatype_get(const struct datatype *ptr) return dtype; } +void __datatype_set(struct expr *expr, const struct datatype *dtype) +{ + const struct datatype *dtype_free; + + dtype_free = expr->dtype; + expr->dtype = dtype; + datatype_free(dtype_free); +} + void datatype_set(struct expr *expr, const struct datatype *dtype) { - if (dtype == expr->dtype) - return; - datatype_free(expr->dtype); - expr->dtype = datatype_get(dtype); + if (dtype != expr->dtype) + __datatype_set(expr, datatype_get(dtype)); } struct datatype *dtype_clone(const struct datatype *orig_dtype) @@ -1133,7 +1141,7 @@ struct datatype *dtype_clone(const struct datatype *orig_dtype) dtype->name = xstrdup(orig_dtype->name); dtype->desc = xstrdup(orig_dtype->desc); dtype->flags = DTYPE_F_ALLOC | orig_dtype->flags; - dtype->refcnt = 0; + dtype->refcnt = 1; return dtype; } @@ -1146,6 +1154,9 @@ void datatype_free(const struct datatype *ptr) return; if (!(dtype->flags & DTYPE_F_ALLOC)) return; + + assert(dtype->refcnt != 0); + if (--dtype->refcnt > 0) return; @@ -1198,7 +1209,7 @@ const struct datatype *set_datatype_alloc(const struct datatype *orig_dtype, /* Restrict dynamic datatype allocation to generic integer datatype. */ if (orig_dtype != &integer_type) - return orig_dtype; + return datatype_get(orig_dtype); dtype = dtype_clone(orig_dtype); dtype->byteorder = byteorder; |