(Disclaimer: Generated with Claude, based on the discussion here #1545 (comment); proof-read by me)
Summary
A recent fix (2b3388f) indirectly addressed a segfault when calling actions with inherited VAR_IN_OUT parameters, but no existing tests covered this case.
Example
// cargo r -- target/demo.st tests/lit/util/printf.pli --linker=clang && ./demo.st.out
PROGRAM mainProg
VAR
fb : fb_t;
localBool: BOOL;
END_VAR
localBool := TRUE;
fb.foo(myInOut := localBool);
localBool := FALSE;
fb.foo(myInOut := localBool);
END_PROGRAM
FUNCTION_BLOCK fb_t
VAR_IN_OUT
myInOut : BOOL;
END_VAR
END_FUNCTION_BLOCK
ACTIONS
ACTION foo
printf('myInout = %d$N', myInOut);
END_ACTION
END_ACTIONS
FUNCTION main
mainProg();
END_FUNCTION
Cause
The generated IR only loaded localBool's value but never stored its address into fb.myInOut, leaving the pointer NULL:
%fb_t = type { ptr, ptr }
; Before (broken)
%load_localBool = load i8, ptr %localBool, align 1 ; loaded but never used
call void @fb_t__foo(ptr %fb) ; myInOut still NULL → segfault
; After (fixed)
%1 = getelementptr inbounds %fb_t, ptr %fb, i32 0, i32 1 ; get myInOut field
store ptr %localBool, ptr %1, align 8 ; store address
call void @fb_t__foo(ptr %fb) ; myInOut now valid
We should add test coverage to prevent regressions.
(Disclaimer: Generated with Claude, based on the discussion here #1545 (comment); proof-read by me)
Summary
A recent fix (2b3388f) indirectly addressed a segfault when calling actions with inherited VAR_IN_OUT parameters, but no existing tests covered this case.
Example
Cause
The generated IR only loaded localBool's value but never stored its address into fb.myInOut, leaving the pointer NULL:
We should add test coverage to prevent regressions.