aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-02-29 13:00:28 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-02-29 13:00:28 -0500
commitab17cf75394b0f100bd18668ce637e9aab6ed1e9 (patch)
treec7fae004d8849a3ce6ff53abcdbcdf55b7baa5fa
parent0f34bd8f534d605d6043387ab0b1fc7f621eb489 (diff)
Flip COW bit when dereferencing pointers
-rw-r--r--compile.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/compile.c b/compile.c
index 536de03e..cf3bed4d 100644
--- a/compile.c
+++ b/compile.c
@@ -937,7 +937,16 @@ CORD compile(env_t *env, ast_t *ast)
auto indexing = Match(ast, Index);
type_t *indexed_type = get_type(env, indexing->indexed);
if (!indexing->index && indexed_type->tag == PointerType) {
- return CORD_all("*(", compile(env, indexing->indexed), ")");
+ auto ptr = Match(indexed_type, PointerType);
+ if (ptr->is_optional)
+ code_err(ast, "This pointer is potentially null, so it can't be safely dereferenced");
+ if (ptr->pointed->tag == ArrayType) {
+ return CORD_all("({ array_t *$arr = ", compile(env, indexing->indexed), "; $arr->data_refcount = 3; *$arr; })");
+ } else if (ptr->pointed->tag == TableType) {
+ return CORD_all("({ table_t *$t = ", compile(env, indexing->indexed), "; Table_mark_copy_on_write($t); *$t; })");
+ } else {
+ return CORD_all("*(", compile(env, indexing->indexed), ")");
+ }
}
type_t *container_t = value_type(indexed_type);
type_t *index_t = get_type(env, indexing->index);