Support returning structures from functions#243
Merged
laurenthuberdeau merged 9 commits intoJun 11, 2026
Conversation
Debian Woody's gcc doesn't support -std=c99.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
The bootstrap of TCC's 64-bit integers is complicated and fragile, requiring a large set of patches and workarounds. It would be much easier (and correct) to bootstrap TCC with a compiler that already supports 64-bit integers, removing the need for much of these patches, and potentially reducing the number of intermediate TCC binaries that must be generated.
However, pnut's integers are limited by the machine's word size, as anything wider breaks the assumption that integers fit in a single machine word. This PR adds support for functions returning structures, which, with the preexisting support for passing structures as argument, unblocks support for 64-bit (and possibly floating point) arithmetic by replacing all wide arithmetic operations by function calls.
Implementation Details
The implementation follows a variant of the System V ABI, requiring the caller to pass to the callee a pointer to the memory location where to write the result. To keep the implementation simple, callers always allocate on the stack a temporary buffer where the value is written to by the callee. After the callee returns control to the caller, the temporary value is then written to its final location or dropped.
A temporary may be used as part of a larger expression, meaning it must outlive the expression that created it. To simplify the code generator, we don't track the exact lifetime of temporaries (nor reuse them) and instead just let them accumulate on the stack until the end of the statement, where they are all freed at once by codegen_statement's stack cleanup.
However, there are cases where a temporary must be freed before the end of the statement to keep the stack balanced:
codegen_rvalue_and_cmp_0.codegen_ternary_arm.codegen_rvalue_and_drop_temps.codegen_rvalue_and_drop_temps.Impact on bootstrap scripts
No size difference for
pnut-shandpnut-awk. 20 more lines for minimalpnut-exe.Main:
PR: