fix: pass plain variable arguments to REFERENCE TO inputs by address (1.0.x) - #1847
Open
ghaith wants to merge 2 commits into
Open
fix: pass plain variable arguments to REFERENCE TO inputs by address (1.0.x)#1847ghaith wants to merge 2 commits into
ghaith wants to merge 2 commits into
Conversation
A plain variable passed to a REFERENCE TO VAR_INPUT of a function or method currently arrives as its value instead of its address. The receiving reference then holds null or a garbage pointer, and writes through it corrupt memory. The tests document the expected address-passing semantics and fail until the call-site lowering is fixed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Function and method call sites loaded the value of a plain variable
argument bound to a REFERENCE TO VAR_INPUT and passed it where the
callee expects an address; the receiving reference ended up null or
pointing at a garbage address. The parameter side now decides: any
REFERENCE TO parameter takes the by-ref argument path, and an omitted
argument receives a freshly allocated dummy address.
New validations for arguments to by-ref parameters (REFERENCE TO,
VAR_IN_OUT, function VAR_OUTPUT, VAR_INPUT {ref}):
- E031 when a REFERENCE TO argument is not a reference (literal,
expression, empty assignment)
- E031 when a REFERENCE TO, VAR_IN_OUT or VAR_OUTPUT argument is a
constant; {ref} inputs keep accepting constants
- E037 when the elementary argument type does not match exactly:
REFERENCE TO rejects any difference, the other kinds reject a
smaller argument (the callee would access memory beyond it, and
VAR_IN_OUT crashed codegen); larger arguments keep the established
implicit-downcast warning
- E030 when a method call omits a REFERENCE TO input; inputs of
stateful POUs keep their persistent binding and stay optional
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Build Artifacts🐧 Linux
From workflow run 🪟 Windows
From workflow run |
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.
Note
This PR was authored by Claude (Anthropic) on behalf of @ghaith.
Backport of #1846 to
release/1.0.x(clean cherry-pick of both commits).Problem
A plain variable passed to a
REFERENCE TOVAR_INPUT of a function or method arrived as its value instead of its address: the caller emittedcall @func(i64 %value)against a callee declared asdefine @func(ptr). The receiving reference ended up null (for zero-valued arguments) or pointing at a garbage address, soREF=assignments from such inputs silently produced unusable references, and writes through them corrupted memory. Certain combinations of these mistyped calls also made the LLVM backend abort withCannot emit physreg copy instruction.Fix
generate_function_argumentsnow routes anyREFERENCE TOparameter through the by-ref argument path (previously only when the argument itself was a reference), matching the callee signature and the existing FB/PROGRAM call path.generate_empty_expressiongives omittedREFERENCE TOarguments a freshly allocated dummy address instead of a garbage value.New validations
Arguments to by-ref parameters (
REFERENCE TO,VAR_IN_OUT, functionVAR_OUTPUT,VAR_INPUT {ref}) are checked following CODESYS semantics (C0041/C0141/C0201):REFERENCE TOargument must be a reference — literals, expressions and empty assignments are rejected.REFERENCE TO,VAR_IN_OUTandVAR_OUTPUT(write access needed).{ref}inputs keep accepting constants and literals (read-only optimization used by the stdlib).REFERENCE TOrejects any difference; the other kinds reject a smaller argument — the callee would access memory beyond the argument's storage, and theVAR_IN_OUTcase previously crashed codegen with an internal Builder error (invalid cast opcode). Larger arguments keep the established E067 implicit-downcast warning, so existing downcast behavior is unchanged.REFERENCE TOinputs (bound per call). Inputs of stateful POUs keep their persistent instance binding and stay optional.Tests
VAR_OUTPUT(REALoutput into anINTvariable) now errors instead of only warning — that direction writes beyond the target variable.Verified on this branch: full workspace test suite and the pointer lit tests.
🤖 Generated with Claude Code