Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tests/driver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ begin_category "Standalone Programs" "Testing checked-in end-to-end programs"
try_file 0 'F(10) = 55' "$TESTS_DIR/fib.c"
try_file 0 $'1\nHello World' "$TESTS_DIR/hello.c"
try_file 0 '' "$TESTS_DIR/strength-reduce.c"
try_file 0 '' "$TESTS_DIR/escaped-param.c"

# The section header table closes an ELF32 image, so e_shoff plus its extent
# must reach exactly the end of the file, including the page padding a static
Expand Down
39 changes: 39 additions & 0 deletions tests/escaped-param.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*

@jserv jserv Sep 17, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The file opens with an empty line where its sibling tests/strength-reduce.c opens with a comment naming the shape it guards. This test depends on a narrow shape (a parameter still sitting in its arrival register, its address taken only after the expression reads it), and nothing in the file says so. A later cleanup could drop the unused p or move &b above the arithmetic, and the test would still pass while covering nothing. Move the explanation from the pull request description into the file:

Suggested change
/*
/* A parameter whose address is taken only after an expression has
* read it is still in the register it arrived in, and its stack slot may not
* exist yet. Reloading it from that slot read whatever sat at offset
* zero of the frame. Keep the `&` after the arithmetic and the
* pointers in place: both are what make this path reachable.
*/

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.

Applied. The file has carried a header comment since the first push, but it explained why no store through the pointer is needed rather than warning against moving the & or dropping p, which is the part a later cleanup would break — your wording covers that, so I took it as is.

One deviation: .ci/check-commentflow.sh reflows the opening /* onto its own line, matching tests/strength-reduce.c. The text is yours; the layout is commentflow's output.

* A parameter whose address is taken only after an expression has read it is
* still in the register it arrived in, and its stack slot may not exist yet.
* Reloading it from that slot read whatever sat at offset zero of the frame.
* Keep the `&` after the arithmetic and the pointers in place: both are what
* make this path reachable.
*/

int sub_then_escape(int a, int b)
{
int x = a - b;
int *p = &b;
return x;
}

int add_then_escape(int a, int b)
{
int x = a + b;
int *p = &b;
return x;
}

int escape_first_operand(int a, int b)
{
int x = a - b;
int *p = &a;
return x;
}

int main()
{
if (sub_then_escape(5, 2) != 3)
return 1;
if (add_then_escape(1, 2) != 3)
return 2;
if (escape_first_operand(5, 2) != 3)
return 3;
return 0;
}