diff --git a/tests/driver.sh b/tests/driver.sh index 2ff6d437..db80f40f 100755 --- a/tests/driver.sh +++ b/tests/driver.sh @@ -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 diff --git a/tests/escaped-param.c b/tests/escaped-param.c new file mode 100644 index 00000000..ecf5e9a7 --- /dev/null +++ b/tests/escaped-param.c @@ -0,0 +1,39 @@ +/* + * 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; +}