Skip to content

transpile: Unset needs_address in various places - #1973

Open
Rua wants to merge 3 commits into
immunant:masterfrom
Rua:needs-address-false
Open

transpile: Unset needs_address in various places#1973
Rua wants to merge 3 commits into
immunant:masterfrom
Rua:needs-address-false

Conversation

@Rua

@Rua Rua commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

needs_address is being set, but it is then passed down to all subexpressions, even those whose address is never actually taken.

@Rua
Rua force-pushed the needs-address-false branch 3 times, most recently from 6a6d1a8 to 4d945e5 Compare August 12, 2026 15:48
@Rua
Rua marked this pull request as ready for review August 12, 2026 18:50
@ahomescu

Copy link
Copy Markdown
Contributor

I think is_pattern from 1776 has the same problem. We might need a larger refactoring to make all these context flags handle recursion correctly. It's weird though, all the mutators on ExprContext return Self so they should make a copy of the context and not modify the original, so what's going on here?

@Rua

Rua commented Aug 15, 2026

Copy link
Copy Markdown
Contributor Author

I think is_pattern from 1776 has the same problem. We might need a larger refactoring to make all these context flags handle recursion correctly.

I have already been looking into the overall issue. Some context flags should be "inherited", others should reset back to a default whenever they are passed to a subexpression.

It's weird though, all the mutators on ExprContext return Self so they should make a copy of the context and not modify the original, so what's going on here?

The problem isn't the copying, it's that the modified context of a parent expression gets passed to all the subexpressions too. So in this case, if needs_address is set when calling convert_expr or such, if the expression consists of further subexpressions, then needs_address will still be set when translating those subexpressions as well. You see this in the tests I've added: if the address is taken of an array-subscript expression, and either the array or the subscript are themselves expression types that are sensitive to the needs_address flag, then those expressions are also translated as if their address is taken, when they shouldn't be.

let arg_expr_kind = &self.ast_context.index_unwrap_parens(arg).kind;

if let &CExprKind::Unary(_, CUnOp::AddressOf, arg, _) = arg_expr_kind {
return self.convert_expr(ctx.used(), arg, None);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want set_needs_address(false) for this one?

There might be a regression here for this test case:

int *deref_addrof_compound(void) {
    return *&(int[]){1, 2, 3};
}

Can you reproduce it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a regression test for it and fixed the issue.

@ahomescu

Copy link
Copy Markdown
Contributor

The problem isn't the copying, it's that the modified context of a parent expression gets passed to all the subexpressions too.

Ah I understand now, it's in the opposite direction of what I thought.

@Rua
Rua force-pushed the needs-address-false branch from 4d945e5 to f187cf4 Compare August 15, 2026 10:11
@Rua
Rua force-pushed the needs-address-false branch from f187cf4 to 0cc2795 Compare August 15, 2026 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants