summaryrefslogtreecommitdiffstats
path: root/src/datatype.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/datatype.c')
-rw-r--r--src/datatype.c23
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;