From b8edb812ff4934c609fdfafe2e1c7f932bc18305 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Fri, 1 Dec 2023 14:31:22 -0300 Subject: [PATCH] hardcfr: make builtin_return tests more portable [PR112334] Rework __builtin_return tests to explicitly call __builtin_apply and use its return value rather than anything else. Also require untyped_assembly. Avoid the noise out of exceptions escaping the builtin-applied function, but add a test to cover their effects as well. for gcc/testsuite/ChangeLog PR target/112334 * c-c++-common/torture/harden-cfr-bret.c: Rework for stricter untyped_return requirements. Require untyped_assembly. * c-c++-common/torture/harden-cfr-bret-except.c: New. * c-c++-common/torture/harden-cfr-bret-always.c: Require untyped_assembly. * c-c++-common/torture/harden-cfr-bret-never.c: Likewise. * c-c++-common/torture/harden-cfr-bret-noopt.c: Likewise. * c-c++-common/torture/harden-cfr-bret-noret.c: Likewise. * c-c++-common/torture/harden-cfr-bret-no-xthrow.c: Likewise. * c-c++-common/torture/harden-cfr-bret-nothrow.c: Likewise. * c-c++-common/torture/harden-cfr-bret-retcl.c: Likewise. --- .../torture/harden-cfr-bret-always.c | 3 ++- .../torture/harden-cfr-bret-except.c | 17 ++++++++++++++ .../torture/harden-cfr-bret-never.c | 3 ++- .../torture/harden-cfr-bret-no-xthrow.c | 3 ++- .../torture/harden-cfr-bret-noopt.c | 3 ++- .../torture/harden-cfr-bret-noret.c | 3 ++- .../torture/harden-cfr-bret-nothrow.c | 3 ++- .../torture/harden-cfr-bret-retcl.c | 3 ++- .../c-c++-common/torture/harden-cfr-bret.c | 23 +++++++++++++++---- 9 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/torture/harden-cfr-bret-except.c diff --git a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-always.c b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-always.c index 779896c60e84..3406c4e6ef9d 100644 --- a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-always.c +++ b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-always.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=always -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=always -fno-exceptions -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-require-effective-target untyped_assembly } */ /* Check that, even enabling all checks before noreturn calls (leaving returning calls enabled), we get checks before __builtin_return without diff --git a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-except.c b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-except.c new file mode 100644 index 000000000000..3acb61cb75a7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-except.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-fharden-control-flow-redundancy -fexceptions -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-require-effective-target untyped_assembly } */ + +/* Check that, with exceptions enabled, even in C, the calls initiated by + builtin_apply are enclosed in cleanup handlers that add extra checks. + Unfortunately, declaring foobar as nothrow is not enough to avoid the + handler around the builtin_apply call, so the other bret tests all use + -fno-exceptions. */ + +#include "harden-cfr-bret.c" + +/* With exceptions, we get an extra check per function, to check before + propagating exceptions, so it's 3 in f and 2 in g. */ +/* { dg-final { scan-tree-dump-times "__hardcfr_check" 5 "hardcfr" } } */ +/* The extra check in g also removes the possibility of inlining the check. */ +/* { dg-final { scan-tree-dump-times "__builtin_trap" 0 "hardcfr" } } */ diff --git a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-never.c b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-never.c index 49ce17f5b937..7f8fb64138df 100644 --- a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-never.c +++ b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-never.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=never -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=never -fno-exceptions -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-require-effective-target untyped_assembly } */ /* Check that, even enabling checks before never noreturn calls (leaving returning calls enabled), we get checks before __builtin_return without diff --git a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-no-xthrow.c b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-no-xthrow.c index 78e5bf414392..07588e8d3c34 100644 --- a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-no-xthrow.c +++ b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-no-xthrow.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=no-xthrow -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=no-xthrow -fno-exceptions -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-require-effective-target untyped_assembly } */ /* Check that, even enabling checks before no-xthrow-throwing noreturn calls (leaving returning calls enabled), we get checks before __builtin_return diff --git a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-noopt.c b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-noopt.c index 1512614791ff..716d9297c8d9 100644 --- a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-noopt.c +++ b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-noopt.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=never -fno-hardcfr-check-returning-calls -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=never -fno-hardcfr-check-returning-calls -fno-exceptions -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-require-effective-target untyped_assembly } */ /* Check that, even disabling checks before both noreturn and returning calls, we still get checks before __builtin_return. */ diff --git a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-noret.c b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-noret.c index fd95bb7e3e33..c6d2baa31203 100644 --- a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-noret.c +++ b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-noret.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-fharden-control-flow-redundancy -fno-hardcfr-check-returning-calls -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-options "-fharden-control-flow-redundancy -fno-hardcfr-check-returning-calls -fno-exceptions -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-require-effective-target untyped_assembly } */ /* Check that, even disabling checks before returning calls (leaving noreturn calls enabled), we still get checks before __builtin_return. */ diff --git a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-nothrow.c b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-nothrow.c index c5c361234c49..2fd0d82c7ea3 100644 --- a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-nothrow.c +++ b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-nothrow.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=nothrow -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=nothrow -fno-exceptions -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-require-effective-target untyped_assembly } */ /* Check that, even enabling checks before nothrow noreturn calls (leaving returning calls enabled), we get checks before __builtin_return without diff --git a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-retcl.c b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-retcl.c index 137dfbb95d6b..b070294fde8a 100644 --- a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-retcl.c +++ b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret-retcl.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ -/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=never -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-options "-fharden-control-flow-redundancy -fhardcfr-check-noreturn-calls=never -fno-exceptions -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-require-effective-target untyped_assembly } */ /* Check that, even disabling checks before noreturn calls (leaving returning calls enabled), we still get checks before __builtin_return. */ diff --git a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret.c b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret.c index b459ff6b8649..b6630a6c8669 100644 --- a/gcc/testsuite/c-c++-common/torture/harden-cfr-bret.c +++ b/gcc/testsuite/c-c++-common/torture/harden-cfr-bret.c @@ -1,14 +1,27 @@ /* { dg-do compile } */ -/* { dg-options "-fharden-control-flow-redundancy -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-options "-fharden-control-flow-redundancy -fno-exceptions -fdump-tree-hardcfr -ffat-lto-objects" } */ +/* { dg-require-effective-target untyped_assembly } */ -int f(int i) { +extern int foobar (void); + +#if __cplusplus +typedef void (*fnt)(...); +#else +typedef void (*fnt)(); +#endif + +int i; + +int f(void) { if (i) - __builtin_return (&i); + __builtin_return (__builtin_apply ((fnt)foobar, + __builtin_apply_args (), 0)); return i; } -int g(int i) { - __builtin_return (&i); +int g(void) { + __builtin_return (__builtin_apply ((fnt)foobar, + __builtin_apply_args (), 0)); } /* Out-of-line checking, before both builtin_return and return in f. */ -- 2.47.2