Matthieu Longo <matthieu.lo...@arm.com> writes: > gcc/testsuite/ChangeLog: > > * g++.target/aarch64/pr94515-1.C: Improve test documentation. > * g++.target/aarch64/pr94515-2.C: Same.
The patch is OK as-is, since it's clearly a strict improvement over the status quo. But a suggestion below: > --- > gcc/testsuite/g++.target/aarch64/pr94515-1.C | 8 ++++++ > gcc/testsuite/g++.target/aarch64/pr94515-2.C | 28 +++++++++++++++----- > 2 files changed, 30 insertions(+), 6 deletions(-) > > diff --git a/gcc/testsuite/g++.target/aarch64/pr94515-2.C > b/gcc/testsuite/g++.target/aarch64/pr94515-2.C > index f4a3333beed..af6b128b8fd 100644 > --- a/gcc/testsuite/g++.target/aarch64/pr94515-2.C > +++ b/gcc/testsuite/g++.target/aarch64/pr94515-2.C > @@ -6,6 +6,7 @@ > volatile int zero = 0; > int global = 0; > > +/* This is a leaf function, so no .cfi_negate_ra_state directive is > expected. */ > __attribute__((noinline)) > int bar(void) > { > @@ -13,29 +14,44 @@ int bar(void) > return 0; > } > > +/* This function does not return normally, so the address is signed but no > + * authentication code is emitted. It means that only one CFI directive is > + * supposed to be emitted at signing time. */ > __attribute__((noinline, noreturn)) > void unwind (void) > { > throw 42; > } > > +/* This function has several return instructions, and alternates different RA > + * states. 4 .cfi_negate_ra_state and a > .cfi_remember_state/.cfi_restore_state > + * should be emitted. > + */ > __attribute__((noinline, noipa)) > int test(int x) > { > - if (x==1) return 2; /* This return path may not use the stack. */ > + // This return path may not use the stack. This means that the return > address > + // won't be signed. > + if (x==1) return 2; > + > + // All the return paths of the code below must have RA mangle state set, > and > + // the return address must be signed. > int y = bar(); > if (y > global) global=y; > - if (y==3) unwind(); /* This return path must have RA mangle state set. */ > - return 0; > + if (y==3) unwind(); // authentication of the return address is not > required. > + return 0; // authentication of the return address is required. > } I wasn't sure from reading this why it would give 4 .cfi_negate_ra_states, and had to run the test to find out. I think a key part is that the current block layout is: A: path to return 0 without assignment to global B: global=y + branch back into A C: return 2 D: unwind so we have: A: sign -> authenticate [2 negate_ra_states + remember_state for B] B: signed [restore_state] C: unsigned [negate_ra_state] D: signed [negate_ra_state] If the order had been ABDC then we would only need 3 negate_ra_states. If the x==1 branch had been: cmp w0, 1 bne .L10 mov w0, 2 ret .L10: followed by the rest of A, B and D, then we would only have needed 2 negate_ra_states. So it might be helpful to give the block layout above too. Like I say, it's just a suggestion though. Thanks, Richard > +/* This function requires only 2 .cfi_negate_ra_state. */ > int main () > { > + // paciasp -> cfi_negate_ra_state: RA_no_signing -> RA_signing_SP > try { > test (zero); > - __builtin_abort (); > + __builtin_abort (); // authentication of the return address is not > required. > } catch (...) { > + // autiasp -> cfi_negate_ra_state: RA_signing_SP -> RA_no_signing > return 0; > } > - __builtin_abort (); > -} > + __builtin_abort (); // authentication of the return address is not > required. > +} > \ No newline at end of file