Describe the bug
Inheritance/interface override of a REFERENCE TO property is rejected. Both an override in a derived FB and an FB implementing an interface that declares a REFERENCE TO property fail at the signature-compatibility check, because the synthesized return-val parameter is named after the enclosing POU rather than after the property.
To Reproduce
// A derived FB overrides a parent's PROPERTY_GET ... REFERENCE TO ...
// We then access through both the parent ref and the child ref.
TYPE Pair :
STRUCT
a : INT;
b : INT;
END_STRUCT
END_TYPE
FUNCTION_BLOCK parent
VAR
_p_parent : Pair;
END_VAR
PROPERTY_GET p : REFERENCE TO Pair
p REF= _p_parent;
END_PROPERTY
END_FUNCTION_BLOCK
FUNCTION_BLOCK child EXTENDS parent
VAR
_p_child : Pair;
END_VAR
// Override the GET: route to the child's own pair instead.
PROPERTY_GET p : REFERENCE TO Pair
p REF= _p_child;
END_PROPERTY
END_FUNCTION_BLOCK
FUNCTION main : INT
VAR
c : child;
v_parent_field : INT;
v_child_field : INT;
END_VAR
c._p_parent.a := 1; // mutate parent's struct directly
c._p_child.a := 2; // mutate child's struct directly
// Read through the overridden child property — should yield 2
v_child_field := c.p.a;
main := v_child_field;
END_FUNCTION
/*
error[E112]: Derived methods with conflicting signatures, parameters do not match:
note[E118]: Expected parameter `__parent___get_p_return_val`
but got `__child___get_p_return_val`
*/
// REFERENCE TO property declared in an INTERFACE,
// accessed through an interface-typed variable.
// Stresses the polymorphism+REFERENCE-TO interaction (the new fat-pointer
// constructor calls in interface dispatch snapshots came from this PR).
TYPE Pair :
STRUCT
a : INT;
b : INT;
END_STRUCT
END_TYPE
INTERFACE IPair
PROPERTY_GET p : REFERENCE TO Pair END_PROPERTY
END_INTERFACE
FUNCTION_BLOCK fb IMPLEMENTS IPair
VAR
_p : Pair;
END_VAR
PROPERTY_GET p : REFERENCE TO Pair
p REF= _p;
END_PROPERTY
END_FUNCTION_BLOCK
FUNCTION main : INT
VAR
x : fb;
iface : IPair;
v : INT;
END_VAR
iface := x;
x._p.a := 13;
v := iface.p.a;
main := v; // expect 13
END_FUNCTION
/*
error[E112]: Derived methods with conflicting signatures, parameters do not match:
note[E118]: Expected parameter `__IPair___get_p_return_val`
but got `__fb___get_p_return_val`
*/
Expected behavior
No error should occur.
Suggested Fix
Keep the per-POU parameter naming (which is genuinely needed to disambiguate same-named properties across unrelated POUs) but teach the signature-compat validator to ignore synthesized parameters. The override check should compare only the user-written property types — i.e. the original REFERENCE TO Pair declaration on both sides — not the synthetic return-val slot that the lowerer is about to add.
Concretely, this probably wants:
- An explicit marker on VariableIndexEntry (e.g. is_synthetic_property_return_ref: bool) set by ReferenceToReturnLowerer::visit_pou when it inserts the new VAR_INPUT variable.
- The override-compatibility checker filters out parameters carrying that flag before comparing parameter lists / return types.
Describe the bug
Inheritance/interface override of a REFERENCE TO property is rejected. Both an override in a derived FB and an FB implementing an interface that declares a REFERENCE TO property fail at the signature-compatibility check, because the synthesized return-val parameter is named after the enclosing POU rather than after the property.
To Reproduce
Expected behavior
No error should occur.
Suggested Fix
Keep the per-POU parameter naming (which is genuinely needed to disambiguate same-named properties across unrelated POUs) but teach the signature-compat validator to ignore synthesized parameters. The override check should compare only the user-written property types — i.e. the original REFERENCE TO Pair declaration on both sides — not the synthetic return-val slot that the lowerer is about to add.
Concretely, this probably wants: