aboutsummaryrefslogtreecommitdiff
path: root/src/compile/promotions.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-11-01 12:58:52 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-11-01 13:00:29 -0400
commit75bb38a10c9fa069cfbc731a1f50e4f977447987 (patch)
treeea73a85757262075f121d304846b256c7a82e54c /src/compile/promotions.c
parent874f7d750f39d154b9ecc9e7fb483eb6e7c43096 (diff)
Fix case where `foo.baz.method()` failed to pass `baz` as `(&(foo.baz))`
when `foo` was a `&Foo` and `baz.method()` takes a `&Baz`.
Diffstat (limited to 'src/compile/promotions.c')
-rw-r--r--src/compile/promotions.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/compile/promotions.c b/src/compile/promotions.c
index 68b4f64c..b3cbb361 100644
--- a/src/compile/promotions.c
+++ b/src/compile/promotions.c
@@ -182,8 +182,10 @@ Text_t compile_to_type(env_t *env, ast_t *ast, type_t *t) {
}
// Promote values to views-of-values if needed:
- if (t->tag == PointerType && Match(t, PointerType)->is_stack && actual->tag != PointerType)
- return Texts("stack(", compile_to_type(env, ast, Match(t, PointerType)->pointed), ")");
+ if (t->tag == PointerType && Match(t, PointerType)->is_stack && actual->tag != PointerType) {
+ if (type_eq(actual, Match(t, PointerType)->pointed) && can_be_mutated(env, ast))
+ return Texts("&(", compile_lvalue(env, ast), ")");
+ }
if (!is_incomplete_type(actual)) {
Text_t code = compile(env, ast);