From: Richard Biener <richard.guenther@gmail.com>
To: Alexandre Oliva <oliva@adacore.com>
Cc: Thomas Schwinge <thomas@codesourcery.com>,
Tobias Burnus <tobias@codesourcery.com>,
gcc-patches@gcc.gnu.org,
Jeremy Bennett <jeremy.bennett@embecosm.com>,
Craig Blackmore <craig.blackmore@embecosm.com>,
Graham Markall <graham.markall@embecosm.com>,
Martin Jambor <mjambor@suse.cz>, Jan Hubicka <hubicka@ucw.cz>,
Jim Wilson <wilson@tuliptree.org>,
Jeff Law <jeffreyalaw@gmail.com>,
Jakub Jelinek <jakub@redhat.com>,
Tom de Vries <tdevries@suse.de>
Subject: Re: [PATCH] strub: enable conditional support
Date: Thu, 7 Dec 2023 08:24:43 +0100 [thread overview]
Message-ID: <CAFiYyc3vw5EQGgXUq3hUyG-MocrSVjGrdCh+pp6UQ-x5ER5A3g@mail.gmail.com> (raw)
In-Reply-To: <orjzpqd6u0.fsf_-_@lxoliva.fsfla.org>
On Thu, Dec 7, 2023 at 4:34 AM Alexandre Oliva <oliva@adacore.com> wrote:
>
> On Dec 6, 2023, Alexandre Oliva <oliva@adacore.com> wrote:
>
> > Disabling the runtime bits is easy, once we determine what condition we
> > wish to test for. I suppose testing for target support in the compiler,
> > issuing a 'sorry' in case the feature is required, would provide
> > something for libgcc configure and testsuite effective-target to test
> > for and decide whether to enable runtime support and run the tests.
>
> Instead of doing something equivalent to an implicit -fstrub=disable,
> that would quietly compile without stack scrubbing, I thought it would
> be safer to be noisy if the feature is used (requested, really) when
> support is not available.
>
>
> Targets that don't expose callee stacks to callers, such as nvptx, as
> well as -fsplit-stack compilations, violate fundamental assumptions of
> the current strub implementation. This patch enables targets to
> disable strub, and disables it when -fsplit-stack is enabled.
>
> When strub support is disabled, the testsuite will now skip strub
> tests, and libgcc will not build the strub runtime components.
>
> Regstrapped on x86_64-linux-gnu. Also tested with an additional patch
> for i386.cc that mirrors the nvptx.cc change, to check that strub gets
> disabled without noisy test results. Ok to install?
OK.
Thanks,
Richard.
>
> for gcc/ChangeLog
>
> * target.def (have_strub_support_for): New hook.
> * doc/tm.texi.in: Document it.
> * doc/tm.texi: Rebuild.
> * ipa-strub.cc: Include target.h.
> (strub_target_support_p): New.
> (can_strub_p): Call it. Test for no flag_split_stack.
> (pass_ipa_strub::adjust_at_calls_call): Check for target
> support.
> * config/nvptx/nvptx.cc (TARGET_HAVE_STRUB_SUPPORT_FOR):
> Disable.
> * doc/sourcebuild.texi (strub): Document new effective
> target.
>
> for gcc/testsuite/ChangeLog
>
> * gcc.dg/strub-split-stack.c: New.
> * gcc.dg/strub-unsupported.c: New.
> * gcc.dg/strub-unsupported-2.c: New.
> * gcc.dg/strub-unsupported-3.c: New.
> * lib/target-supports.exp (check_effective_target_strub): New.
> * c-c++-common/strub-O0.c: Require effective target strub.
> * c-c++-common/strub-O1.c: Likewise.
> * c-c++-common/strub-O2.c: Likewise.
> * c-c++-common/strub-O2fni.c: Likewise.
> * c-c++-common/strub-O3.c: Likewise.
> * c-c++-common/strub-O3fni.c: Likewise.
> * c-c++-common/strub-Og.c: Likewise.
> * c-c++-common/strub-Os.c: Likewise.
> * c-c++-common/strub-all1.c: Likewise.
> * c-c++-common/strub-all2.c: Likewise.
> * c-c++-common/strub-apply1.c: Likewise.
> * c-c++-common/strub-apply2.c: Likewise.
> * c-c++-common/strub-apply3.c: Likewise.
> * c-c++-common/strub-apply4.c: Likewise.
> * c-c++-common/strub-at-calls1.c: Likewise.
> * c-c++-common/strub-at-calls2.c: Likewise.
> * c-c++-common/strub-defer-O1.c: Likewise.
> * c-c++-common/strub-defer-O2.c: Likewise.
> * c-c++-common/strub-defer-O3.c: Likewise.
> * c-c++-common/strub-defer-Os.c: Likewise.
> * c-c++-common/strub-internal1.c: Likewise.
> * c-c++-common/strub-internal2.c: Likewise.
> * c-c++-common/strub-parms1.c: Likewise.
> * c-c++-common/strub-parms2.c: Likewise.
> * c-c++-common/strub-parms3.c: Likewise.
> * c-c++-common/strub-relaxed1.c: Likewise.
> * c-c++-common/strub-relaxed2.c: Likewise.
> * c-c++-common/strub-short-O0-exc.c: Likewise.
> * c-c++-common/strub-short-O0.c: Likewise.
> * c-c++-common/strub-short-O1.c: Likewise.
> * c-c++-common/strub-short-O2.c: Likewise.
> * c-c++-common/strub-short-O3.c: Likewise.
> * c-c++-common/strub-short-Os.c: Likewise.
> * c-c++-common/strub-strict1.c: Likewise.
> * c-c++-common/strub-strict2.c: Likewise.
> * c-c++-common/strub-tail-O1.c: Likewise.
> * c-c++-common/strub-tail-O2.c: Likewise.
> * c-c++-common/strub-var1.c: Likewise.
> * c-c++-common/torture/strub-callable1.c: Likewise.
> * c-c++-common/torture/strub-callable2.c: Likewise.
> * c-c++-common/torture/strub-const1.c: Likewise.
> * c-c++-common/torture/strub-const2.c: Likewise.
> * c-c++-common/torture/strub-const3.c: Likewise.
> * c-c++-common/torture/strub-const4.c: Likewise.
> * c-c++-common/torture/strub-data1.c: Likewise.
> * c-c++-common/torture/strub-data2.c: Likewise.
> * c-c++-common/torture/strub-data3.c: Likewise.
> * c-c++-common/torture/strub-data4.c: Likewise.
> * c-c++-common/torture/strub-data5.c: Likewise.
> * c-c++-common/torture/strub-indcall1.c: Likewise.
> * c-c++-common/torture/strub-indcall2.c: Likewise.
> * c-c++-common/torture/strub-indcall3.c: Likewise.
> * c-c++-common/torture/strub-inlinable1.c: Likewise.
> * c-c++-common/torture/strub-inlinable2.c: Likewise.
> * c-c++-common/torture/strub-ptrfn1.c: Likewise.
> * c-c++-common/torture/strub-ptrfn2.c: Likewise.
> * c-c++-common/torture/strub-ptrfn3.c: Likewise.
> * c-c++-common/torture/strub-ptrfn4.c: Likewise.
> * c-c++-common/torture/strub-pure1.c: Likewise.
> * c-c++-common/torture/strub-pure2.c: Likewise.
> * c-c++-common/torture/strub-pure3.c: Likewise.
> * c-c++-common/torture/strub-pure4.c: Likewise.
> * c-c++-common/torture/strub-run1.c: Likewise.
> * c-c++-common/torture/strub-run2.c: Likewise.
> * c-c++-common/torture/strub-run3.c: Likewise.
> * c-c++-common/torture/strub-run4.c: Likewise.
> * c-c++-common/torture/strub-run4c.c: Likewise.
> * c-c++-common/torture/strub-run4d.c: Likewise.
> * c-c++-common/torture/strub-run4i.c: Likewise.
> * g++.dg/strub-run1.C: Likewise.
> * g++.dg/torture/strub-init1.C: Likewise.
> * g++.dg/torture/strub-init2.C: Likewise.
> * g++.dg/torture/strub-init3.C: Likewise.
> * gnat.dg/strub_attr.adb: Likewise.
> * gnat.dg/strub_ind.adb: Likewise.
> * gnat.dg/strub_access.adb: Likewise.
> * gnat.dg/strub_access1.adb: Likewise.
> * gnat.dg/strub_disp.adb: Likewise.
> * gnat.dg/strub_disp1.adb: Likewise.
> * gnat.dg/strub_ind1.adb: Likewise.
> * gnat.dg/strub_ind2.adb: Likewise.
> * gnat.dg/strub_intf.adb: Likewise.
> * gnat.dg/strub_intf1.adb: Likewise.
> * gnat.dg/strub_intf2.adb: Likewise.
> * gnat.dg/strub_renm.adb: Likewise.
> * gnat.dg/strub_renm1.adb: Likewise.
> * gnat.dg/strub_renm2.adb: Likewise.
> * gnat.dg/strub_var.adb: Likewise.
> * gnat.dg/strub_var1.adb: Likewise.
>
> for libgcc/ChangeLog
>
> * configure.ac: Check for strub support.
> * configure: Rebuilt.
> * Makefile.in: Compile strub.c conditionally.
> ---
> gcc/config/nvptx/nvptx.cc | 3 +
> gcc/doc/sourcebuild.texi | 3 +
> gcc/doc/tm.texi | 6 ++
> gcc/doc/tm.texi.in | 2 +
> gcc/ipa-strub.cc | 54 +++++++++++++++++++-
> gcc/target.def | 8 +++
> gcc/testsuite/c-c++-common/strub-O0.c | 1
> gcc/testsuite/c-c++-common/strub-O1.c | 1
> gcc/testsuite/c-c++-common/strub-O2.c | 1
> gcc/testsuite/c-c++-common/strub-O2fni.c | 1
> gcc/testsuite/c-c++-common/strub-O3.c | 1
> gcc/testsuite/c-c++-common/strub-O3fni.c | 1
> gcc/testsuite/c-c++-common/strub-Og.c | 1
> gcc/testsuite/c-c++-common/strub-Os.c | 1
> gcc/testsuite/c-c++-common/strub-all1.c | 1
> gcc/testsuite/c-c++-common/strub-all2.c | 1
> gcc/testsuite/c-c++-common/strub-apply1.c | 1
> gcc/testsuite/c-c++-common/strub-apply2.c | 1
> gcc/testsuite/c-c++-common/strub-apply3.c | 1
> gcc/testsuite/c-c++-common/strub-apply4.c | 1
> gcc/testsuite/c-c++-common/strub-at-calls1.c | 1
> gcc/testsuite/c-c++-common/strub-at-calls2.c | 1
> gcc/testsuite/c-c++-common/strub-defer-O1.c | 1
> gcc/testsuite/c-c++-common/strub-defer-O2.c | 1
> gcc/testsuite/c-c++-common/strub-defer-O3.c | 1
> gcc/testsuite/c-c++-common/strub-defer-Os.c | 1
> gcc/testsuite/c-c++-common/strub-internal1.c | 1
> gcc/testsuite/c-c++-common/strub-internal2.c | 1
> gcc/testsuite/c-c++-common/strub-parms1.c | 1
> gcc/testsuite/c-c++-common/strub-parms2.c | 1
> gcc/testsuite/c-c++-common/strub-parms3.c | 1
> gcc/testsuite/c-c++-common/strub-relaxed1.c | 1
> gcc/testsuite/c-c++-common/strub-relaxed2.c | 1
> gcc/testsuite/c-c++-common/strub-short-O0-exc.c | 1
> gcc/testsuite/c-c++-common/strub-short-O0.c | 1
> gcc/testsuite/c-c++-common/strub-short-O1.c | 1
> gcc/testsuite/c-c++-common/strub-short-O2.c | 1
> gcc/testsuite/c-c++-common/strub-short-O3.c | 1
> gcc/testsuite/c-c++-common/strub-short-Os.c | 1
> gcc/testsuite/c-c++-common/strub-split-stack.c | 10 ++++
> gcc/testsuite/c-c++-common/strub-strict1.c | 1
> gcc/testsuite/c-c++-common/strub-strict2.c | 1
> gcc/testsuite/c-c++-common/strub-tail-O1.c | 1
> gcc/testsuite/c-c++-common/strub-tail-O2.c | 1
> gcc/testsuite/c-c++-common/strub-unsupported-2.c | 13 +++++
> gcc/testsuite/c-c++-common/strub-unsupported-3.c | 18 +++++++
> gcc/testsuite/c-c++-common/strub-unsupported.c | 21 ++++++++
> gcc/testsuite/c-c++-common/strub-var1.c | 1
> .../c-c++-common/torture/strub-callable1.c | 1
> .../c-c++-common/torture/strub-callable2.c | 1
> gcc/testsuite/c-c++-common/torture/strub-const1.c | 1
> gcc/testsuite/c-c++-common/torture/strub-const2.c | 1
> gcc/testsuite/c-c++-common/torture/strub-const3.c | 1
> gcc/testsuite/c-c++-common/torture/strub-const4.c | 1
> gcc/testsuite/c-c++-common/torture/strub-data1.c | 1
> gcc/testsuite/c-c++-common/torture/strub-data2.c | 1
> gcc/testsuite/c-c++-common/torture/strub-data3.c | 1
> gcc/testsuite/c-c++-common/torture/strub-data4.c | 1
> gcc/testsuite/c-c++-common/torture/strub-data5.c | 1
> .../c-c++-common/torture/strub-indcall1.c | 1
> .../c-c++-common/torture/strub-indcall2.c | 1
> .../c-c++-common/torture/strub-indcall3.c | 1
> .../c-c++-common/torture/strub-inlinable1.c | 1
> .../c-c++-common/torture/strub-inlinable2.c | 1
> gcc/testsuite/c-c++-common/torture/strub-ptrfn1.c | 1
> gcc/testsuite/c-c++-common/torture/strub-ptrfn2.c | 1
> gcc/testsuite/c-c++-common/torture/strub-ptrfn3.c | 1
> gcc/testsuite/c-c++-common/torture/strub-ptrfn4.c | 1
> gcc/testsuite/c-c++-common/torture/strub-pure1.c | 1
> gcc/testsuite/c-c++-common/torture/strub-pure2.c | 1
> gcc/testsuite/c-c++-common/torture/strub-pure3.c | 1
> gcc/testsuite/c-c++-common/torture/strub-pure4.c | 1
> gcc/testsuite/c-c++-common/torture/strub-run1.c | 1
> gcc/testsuite/c-c++-common/torture/strub-run2.c | 1
> gcc/testsuite/c-c++-common/torture/strub-run3.c | 1
> gcc/testsuite/c-c++-common/torture/strub-run4.c | 1
> gcc/testsuite/c-c++-common/torture/strub-run4c.c | 1
> gcc/testsuite/c-c++-common/torture/strub-run4d.c | 1
> gcc/testsuite/c-c++-common/torture/strub-run4i.c | 1
> gcc/testsuite/g++.dg/strub-run1.C | 1
> gcc/testsuite/g++.dg/torture/strub-init1.C | 1
> gcc/testsuite/g++.dg/torture/strub-init2.C | 1
> gcc/testsuite/g++.dg/torture/strub-init3.C | 1
> gcc/testsuite/gnat.dg/strub_access.adb | 1
> gcc/testsuite/gnat.dg/strub_access1.adb | 1
> gcc/testsuite/gnat.dg/strub_attr.adb | 1
> gcc/testsuite/gnat.dg/strub_disp.adb | 1
> gcc/testsuite/gnat.dg/strub_disp1.adb | 1
> gcc/testsuite/gnat.dg/strub_ind.adb | 1
> gcc/testsuite/gnat.dg/strub_ind1.adb | 1
> gcc/testsuite/gnat.dg/strub_ind2.adb | 1
> gcc/testsuite/gnat.dg/strub_intf.adb | 1
> gcc/testsuite/gnat.dg/strub_intf1.adb | 1
> gcc/testsuite/gnat.dg/strub_intf2.adb | 1
> gcc/testsuite/gnat.dg/strub_renm.adb | 1
> gcc/testsuite/gnat.dg/strub_renm1.adb | 1
> gcc/testsuite/gnat.dg/strub_renm2.adb | 1
> gcc/testsuite/gnat.dg/strub_var.adb | 1
> gcc/testsuite/gnat.dg/strub_var1.adb | 1
> gcc/testsuite/lib/target-supports.exp | 7 +++
> libgcc/Makefile.in | 2 -
> libgcc/configure | 26 ++++++++++
> libgcc/configure.ac | 13 +++++
> 103 files changed, 272 insertions(+), 3 deletions(-)
> create mode 100644 gcc/testsuite/c-c++-common/strub-split-stack.c
> create mode 100644 gcc/testsuite/c-c++-common/strub-unsupported-2.c
> create mode 100644 gcc/testsuite/c-c++-common/strub-unsupported-3.c
> create mode 100644 gcc/testsuite/c-c++-common/strub-unsupported.c
>
> diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc
> index ae20802c87996..3fb1deb70fda1 100644
> --- a/gcc/config/nvptx/nvptx.cc
> +++ b/gcc/config/nvptx/nvptx.cc
> @@ -7789,6 +7789,9 @@ nvptx_asm_output_def_from_decls (FILE *stream, tree name, tree value)
> #undef TARGET_LIBC_HAS_FUNCTION
> #define TARGET_LIBC_HAS_FUNCTION nvptx_libc_has_function
>
> +#undef TARGET_HAVE_STRUB_SUPPORT_FOR
> +#define TARGET_HAVE_STRUB_SUPPORT_FOR hook_bool_tree_false
> +
> struct gcc_target targetm = TARGET_INITIALIZER;
>
> #include "gt-nvptx.h"
> diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
> index c990902685417..26a7e9c350703 100644
> --- a/gcc/doc/sourcebuild.texi
> +++ b/gcc/doc/sourcebuild.texi
> @@ -2983,6 +2983,9 @@ Target supports statically linking @samp{libgfortran}.
> @item string_merging
> Target supports merging string constants at link time.
>
> +@item strub
> +Target supports attribute @code{strub} for stack scrubbing.
> +
> @item ucn
> Target supports compiling and assembling UCN.
>
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index 89a1735dd7992..768ada0af5222 100644
> --- a/gcc/doc/tm.texi
> +++ b/gcc/doc/tm.texi
> @@ -3450,6 +3450,12 @@ in DWARF 2 debug information. The default is zero. A different value
> may reduce the size of debug information on some ports.
> @end defmac
>
> +@deftypefn {Target Hook} bool TARGET_HAVE_STRUB_SUPPORT_FOR (tree)
> +Returns true if the target supports stack scrubbing for the given function
> +or type, otherwise return false. The default implementation always returns
> +true.
> +@end deftypefn
> +
> @defmac TARGET_STRUB_USE_DYNAMIC_ARRAY
> If defined to nonzero, @code{__strub_leave} will allocate a dynamic
> array covering the stack range that needs scrubbing before clearing it.
> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
> index ebc1d3de5caaa..4fe0805394ea4 100644
> --- a/gcc/doc/tm.texi.in
> +++ b/gcc/doc/tm.texi.in
> @@ -2686,6 +2686,8 @@ in DWARF 2 debug information. The default is zero. A different value
> may reduce the size of debug information on some ports.
> @end defmac
>
> +@hook TARGET_HAVE_STRUB_SUPPORT_FOR
> +
> @defmac TARGET_STRUB_USE_DYNAMIC_ARRAY
> If defined to nonzero, @code{__strub_leave} will allocate a dynamic
> array covering the stack range that needs scrubbing before clearing it.
> diff --git a/gcc/ipa-strub.cc b/gcc/ipa-strub.cc
> index 293bec132b885..2afb7a455751d 100644
> --- a/gcc/ipa-strub.cc
> +++ b/gcc/ipa-strub.cc
> @@ -60,6 +60,7 @@ along with GCC; see the file COPYING3. If not see
> #include "ipa-strub.h"
> #include "symtab-thunks.h"
> #include "attr-fnspec.h"
> +#include "target.h"
>
> /* This file introduces two passes that, together, implement
> machine-independent stack scrubbing, strub for short. It arranges
> @@ -631,17 +632,60 @@ strub_always_inline_p (cgraph_node *node)
> return lookup_attribute ("always_inline", DECL_ATTRIBUTES (node->decl));
> }
>
> +/* Return TRUE iff the target has strub support for T, a function
> + decl, or a type used in an indirect call, and optionally REPORT the
> + reasons for ineligibility. If T is a type and error REPORTing is
> + enabled, the LOCation (of the indirect call) should be provided. */
> +static inline bool
> +strub_target_support_p (tree t, bool report = false,
> + location_t loc = UNKNOWN_LOCATION)
> +{
> + bool result = true;
> +
> + if (!targetm.have_strub_support_for (t))
> + {
> + result = false;
> +
> + if (!report)
> + return result;
> +
> + if (DECL_P (t))
> + sorry_at (DECL_SOURCE_LOCATION (t),
> + "%qD is not eligible for %<strub%>"
> + " on the target system", t);
> + else
> + sorry_at (loc,
> + "unsupported %<strub%> call"
> + " on the target system");
> + }
> +
> + return result;
> +}
> +
> /* Return TRUE iff NODE is potentially eligible for any strub-enabled mode, and
> optionally REPORT the reasons for ineligibility. */
>
> static inline bool
> can_strub_p (cgraph_node *node, bool report = false)
> {
> - bool result = true;
> + bool result = strub_target_support_p (node->decl, report);
>
> - if (!report && strub_always_inline_p (node))
> + if (!report && (!result || strub_always_inline_p (node)))
> return result;
>
> + if (flag_split_stack)
> + {
> + result = false;
> +
> + if (!report)
> + return result;
> +
> + sorry_at (DECL_SOURCE_LOCATION (node->decl),
> + "%qD is not eligible for %<strub%>"
> + " because %<-fsplit-stack%> is enabled",
> + node->decl);
> + }
> +
> if (lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
> {
> result = false;
> @@ -2417,6 +2461,12 @@ pass_ipa_strub::adjust_at_calls_call (cgraph_edge *e, int named_args,
> && (TREE_TYPE (gimple_call_arg (ocall, named_args))
> == get_pwmt ())));
>
> + tree tsup;
> + if (!(tsup = gimple_call_fndecl (ocall)))
> + tsup = TREE_TYPE (TREE_TYPE (gimple_call_fn (ocall)));
> + if (!strub_target_support_p (tsup, true, gimple_location (ocall)))
> + return;
> +
> /* If we're already within a strub context, pass on the incoming watermark
> pointer, and omit the enter and leave calls around the modified call, as an
> optimization, or as a means to satisfy a tail-call requirement. */
> diff --git a/gcc/target.def b/gcc/target.def
> index 52b83e091b94b..08218f3a42adf 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -4457,6 +4457,14 @@ otherwise return false. The default implementation always returns true.",
> bool, (void),
> hook_bool_void_true)
>
> +DEFHOOK
> +(have_strub_support_for,
> + "Returns true if the target supports stack scrubbing for the given function\n\
> +or type, otherwise return false. The default implementation always returns\n\
> +true.",
> + bool, (tree),
> + hook_bool_tree_true)
> +
> DEFHOOK
> (have_speculation_safe_value,
> "This hook is used to determine the level of target support for\n\
> diff --git a/gcc/testsuite/c-c++-common/strub-O0.c b/gcc/testsuite/c-c++-common/strub-O0.c
> index c7a79a6ea0d8a..f0a3f7b4c6f9a 100644
> --- a/gcc/testsuite/c-c++-common/strub-O0.c
> +++ b/gcc/testsuite/c-c++-common/strub-O0.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O0 -fstrub=strict -fdump-rtl-expand" } */
> +/* { dg-require-effective-target strub } */
>
> /* At -O0, none of the strub builtins are expanded inline. */
>
> diff --git a/gcc/testsuite/c-c++-common/strub-O1.c b/gcc/testsuite/c-c++-common/strub-O1.c
> index 96285c975d98e..50403426b18f2 100644
> --- a/gcc/testsuite/c-c++-common/strub-O1.c
> +++ b/gcc/testsuite/c-c++-common/strub-O1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O1 -fstrub=strict -fdump-rtl-expand" } */
> +/* { dg-require-effective-target strub } */
>
> /* At -O1, without -fno-inline, we fully expand enter, but neither update nor
> leave. */
> diff --git a/gcc/testsuite/c-c++-common/strub-O2.c b/gcc/testsuite/c-c++-common/strub-O2.c
> index 8edc0d8aa1321..37e02998e318e 100644
> --- a/gcc/testsuite/c-c++-common/strub-O2.c
> +++ b/gcc/testsuite/c-c++-common/strub-O2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O2 -fstrub=strict -fdump-rtl-expand" } */
> +/* { dg-require-effective-target strub } */
>
> /* At -O2, without -fno-inline, we fully expand enter and update, and add a test
> around the leave call. */
> diff --git a/gcc/testsuite/c-c++-common/strub-O2fni.c b/gcc/testsuite/c-c++-common/strub-O2fni.c
> index c6d900cf3c45b..905e2c6b2ffca 100644
> --- a/gcc/testsuite/c-c++-common/strub-O2fni.c
> +++ b/gcc/testsuite/c-c++-common/strub-O2fni.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O2 -fstrub=strict -fdump-rtl-expand -fno-inline" } */
> +/* { dg-require-effective-target strub } */
>
> /* With -fno-inline, none of the strub builtins are inlined. */
>
> diff --git a/gcc/testsuite/c-c++-common/strub-O3.c b/gcc/testsuite/c-c++-common/strub-O3.c
> index 33ee465e51cb6..3bbf132bdf1ea 100644
> --- a/gcc/testsuite/c-c++-common/strub-O3.c
> +++ b/gcc/testsuite/c-c++-common/strub-O3.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O3 -fstrub=strict -fdump-rtl-expand" } */
> +/* { dg-require-effective-target strub } */
>
> int __attribute__ ((__strub__)) var;
>
> diff --git a/gcc/testsuite/c-c++-common/strub-O3fni.c b/gcc/testsuite/c-c++-common/strub-O3fni.c
> index 2936f82079e18..c46fce38e5c91 100644
> --- a/gcc/testsuite/c-c++-common/strub-O3fni.c
> +++ b/gcc/testsuite/c-c++-common/strub-O3fni.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O3 -fstrub=strict -fdump-rtl-expand -fno-inline" } */
> +/* { dg-require-effective-target strub } */
>
> /* With -fno-inline, none of the strub builtins are inlined. */
>
> diff --git a/gcc/testsuite/c-c++-common/strub-Og.c b/gcc/testsuite/c-c++-common/strub-Og.c
> index 479746e57d87e..3b8eb19765cd6 100644
> --- a/gcc/testsuite/c-c++-common/strub-Og.c
> +++ b/gcc/testsuite/c-c++-common/strub-Og.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-Og -fstrub=strict -fdump-rtl-expand" } */
> +/* { dg-require-effective-target strub } */
>
> /* At -Og, without -fno-inline, we fully expand enter, but neither update nor
> leave. */
> diff --git a/gcc/testsuite/c-c++-common/strub-Os.c b/gcc/testsuite/c-c++-common/strub-Os.c
> index 2241d4ea07f27..8cfb253d6764c 100644
> --- a/gcc/testsuite/c-c++-common/strub-Os.c
> +++ b/gcc/testsuite/c-c++-common/strub-Os.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-Os -fstrub=strict -fdump-rtl-expand" } */
> +/* { dg-require-effective-target strub } */
>
> /* At -Os, without -fno-inline, we fully expand enter, and also update. The
> expanded update might be larger than a call proper, but argument saving and
> diff --git a/gcc/testsuite/c-c++-common/strub-all1.c b/gcc/testsuite/c-c++-common/strub-all1.c
> index a322bcc5da606..2037f681f2973 100644
> --- a/gcc/testsuite/c-c++-common/strub-all1.c
> +++ b/gcc/testsuite/c-c++-common/strub-all1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=all -fdump-ipa-strubm -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* h becomes STRUB_CALLABLE, rather than STRUB_INLINABLE, because of the
> strub-enabling -fstrub flag, and gets inlined before pass_ipa_strub. */
> diff --git a/gcc/testsuite/c-c++-common/strub-all2.c b/gcc/testsuite/c-c++-common/strub-all2.c
> index db60026d0e080..c026e7d9d289b 100644
> --- a/gcc/testsuite/c-c++-common/strub-all2.c
> +++ b/gcc/testsuite/c-c++-common/strub-all2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=all -fdump-ipa-strubm -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* g becomes STRUB_INTERNAL, because of the flag. Without inline, force_output
> is set for static non-inline functions when not optimizing, and that keeps
> diff --git a/gcc/testsuite/c-c++-common/strub-apply1.c b/gcc/testsuite/c-c++-common/strub-apply1.c
> index 2f462adc1efe0..3edc89c54eea1 100644
> --- a/gcc/testsuite/c-c++-common/strub-apply1.c
> +++ b/gcc/testsuite/c-c++-common/strub-apply1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict" } */
> +/* { dg-require-effective-target strub } */
>
> void __attribute__ ((__strub__ ("callable")))
> apply_function (void *args)
> diff --git a/gcc/testsuite/c-c++-common/strub-apply2.c b/gcc/testsuite/c-c++-common/strub-apply2.c
> index a5d7551f5da5c..838fc75273450 100644
> --- a/gcc/testsuite/c-c++-common/strub-apply2.c
> +++ b/gcc/testsuite/c-c++-common/strub-apply2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict" } */
> +/* { dg-require-effective-target strub } */
>
> extern void __attribute__ ((__strub__))
> apply_function (void *args);
> diff --git a/gcc/testsuite/c-c++-common/strub-apply3.c b/gcc/testsuite/c-c++-common/strub-apply3.c
> index 64422a0d1e880..0206e4d930e7d 100644
> --- a/gcc/testsuite/c-c++-common/strub-apply3.c
> +++ b/gcc/testsuite/c-c++-common/strub-apply3.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict" } */
> +/* { dg-require-effective-target strub } */
>
> void __attribute__ ((__strub__))
> apply_function (void *args)
> diff --git a/gcc/testsuite/c-c++-common/strub-apply4.c b/gcc/testsuite/c-c++-common/strub-apply4.c
> index 15ffaa031b899..e82504728b2c6 100644
> --- a/gcc/testsuite/c-c++-common/strub-apply4.c
> +++ b/gcc/testsuite/c-c++-common/strub-apply4.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O2 -fstrub=strict -fdump-ipa-strubm" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that implicit enabling of strub mode selects internal strub when the
> function uses __builtin_apply_args, that prevents the optimization to
> diff --git a/gcc/testsuite/c-c++-common/strub-at-calls1.c b/gcc/testsuite/c-c++-common/strub-at-calls1.c
> index b70843b4215a4..a20acc0a48a58 100644
> --- a/gcc/testsuite/c-c++-common/strub-at-calls1.c
> +++ b/gcc/testsuite/c-c++-common/strub-at-calls1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=at-calls -fdump-ipa-strubm -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* h becomes STRUB_CALLABLE, rather than STRUB_INLINABLE, because of the
> strub-enabling -fstrub flag, and gets inlined before pass_ipa_strub. */
> diff --git a/gcc/testsuite/c-c++-common/strub-at-calls2.c b/gcc/testsuite/c-c++-common/strub-at-calls2.c
> index 97a3988a6b922..7915b33a39a0a 100644
> --- a/gcc/testsuite/c-c++-common/strub-at-calls2.c
> +++ b/gcc/testsuite/c-c++-common/strub-at-calls2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=at-calls -fdump-ipa-strubm -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* g does NOT become STRUB_AT_CALLS because it's not viable. Without inline,
> force_output is set for static non-inline functions when not optimizing, and
> diff --git a/gcc/testsuite/c-c++-common/strub-defer-O1.c b/gcc/testsuite/c-c++-common/strub-defer-O1.c
> index 3d73431b3dcd3..3689998b5a323 100644
> --- a/gcc/testsuite/c-c++-common/strub-defer-O1.c
> +++ b/gcc/testsuite/c-c++-common/strub-defer-O1.c
> @@ -1,5 +1,6 @@
> /* { dg-do run } */
> /* { dg-options "-fstrub=strict -O1" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that a strub function called by another strub function does NOT defer
> the strubbing to its caller at -O1. */
> diff --git a/gcc/testsuite/c-c++-common/strub-defer-O2.c b/gcc/testsuite/c-c++-common/strub-defer-O2.c
> index fddf3c745e7e6..9e01949db6be9 100644
> --- a/gcc/testsuite/c-c++-common/strub-defer-O2.c
> +++ b/gcc/testsuite/c-c++-common/strub-defer-O2.c
> @@ -1,5 +1,6 @@
> /* { dg-do run } */
> /* { dg-options "-fstrub=strict -O2" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that a strub function called by another strub function does NOT defer
> the strubbing to its caller at -O2. */
> diff --git a/gcc/testsuite/c-c++-common/strub-defer-O3.c b/gcc/testsuite/c-c++-common/strub-defer-O3.c
> index 7ebc65b58dd72..40ee8edd1e0e6 100644
> --- a/gcc/testsuite/c-c++-common/strub-defer-O3.c
> +++ b/gcc/testsuite/c-c++-common/strub-defer-O3.c
> @@ -1,5 +1,6 @@
> /* { dg-do run } */
> /* { dg-options "-fstrub=strict -O3" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that a strub function called by another strub function defers the
> strubbing to its caller at -O3. */
> diff --git a/gcc/testsuite/c-c++-common/strub-defer-Os.c b/gcc/testsuite/c-c++-common/strub-defer-Os.c
> index fbaf85fe0fafe..67ea9f0463975 100644
> --- a/gcc/testsuite/c-c++-common/strub-defer-Os.c
> +++ b/gcc/testsuite/c-c++-common/strub-defer-Os.c
> @@ -1,5 +1,6 @@
> /* { dg-do run } */
> /* { dg-options "-fstrub=strict -Os" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that a strub function called by another strub function defers the
> strubbing to its caller at -Os. */
> diff --git a/gcc/testsuite/c-c++-common/strub-internal1.c b/gcc/testsuite/c-c++-common/strub-internal1.c
> index e9d7b7b9ee0a8..d17254904e50a 100644
> --- a/gcc/testsuite/c-c++-common/strub-internal1.c
> +++ b/gcc/testsuite/c-c++-common/strub-internal1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=internal -fdump-ipa-strubm -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* h becomes STRUB_CALLABLE, rather than STRUB_INLINABLE, because of the
> strub-enabling -fstrub flag, and gets inlined before pass_ipa_strub. */
> diff --git a/gcc/testsuite/c-c++-common/strub-internal2.c b/gcc/testsuite/c-c++-common/strub-internal2.c
> index 8b8e15a51c71c..afc9189701f82 100644
> --- a/gcc/testsuite/c-c++-common/strub-internal2.c
> +++ b/gcc/testsuite/c-c++-common/strub-internal2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=internal -fdump-ipa-strubm -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* g becomes STRUB_INTERNAL, because of the flag. */
> static void
> diff --git a/gcc/testsuite/c-c++-common/strub-parms1.c b/gcc/testsuite/c-c++-common/strub-parms1.c
> index 0a4a7539d3489..f410b268971a6 100644
> --- a/gcc/testsuite/c-c++-common/strub-parms1.c
> +++ b/gcc/testsuite/c-c++-common/strub-parms1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> #include <stdarg.h>
>
> diff --git a/gcc/testsuite/c-c++-common/strub-parms2.c b/gcc/testsuite/c-c++-common/strub-parms2.c
> index 147171d96d5a1..6f572115a88c3 100644
> --- a/gcc/testsuite/c-c++-common/strub-parms2.c
> +++ b/gcc/testsuite/c-c++-common/strub-parms2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> #include <stdarg.h>
>
> diff --git a/gcc/testsuite/c-c++-common/strub-parms3.c b/gcc/testsuite/c-c++-common/strub-parms3.c
> index 4e92682895a43..7383fea9ce881 100644
> --- a/gcc/testsuite/c-c++-common/strub-parms3.c
> +++ b/gcc/testsuite/c-c++-common/strub-parms3.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that uses of a strub variable implicitly enables internal strub for
> publicly-visible functions, and causes the same transformations to their
> diff --git a/gcc/testsuite/c-c++-common/strub-relaxed1.c b/gcc/testsuite/c-c++-common/strub-relaxed1.c
> index e2f9d8aebca58..d2b4b52c51e60 100644
> --- a/gcc/testsuite/c-c++-common/strub-relaxed1.c
> +++ b/gcc/testsuite/c-c++-common/strub-relaxed1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=relaxed -fdump-ipa-strubm -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* The difference between relaxed and strict in this case is that we accept the
> call from one internal-strub function to another. Without the error,
> diff --git a/gcc/testsuite/c-c++-common/strub-relaxed2.c b/gcc/testsuite/c-c++-common/strub-relaxed2.c
> index 98474435d2e59..9e5a8e76b6c3d 100644
> --- a/gcc/testsuite/c-c++-common/strub-relaxed2.c
> +++ b/gcc/testsuite/c-c++-common/strub-relaxed2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=relaxed -fdump-ipa-strubm -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* The difference between relaxed and strict in this case is that we accept the
> call from one internal-strub function to another. */
> diff --git a/gcc/testsuite/c-c++-common/strub-short-O0-exc.c b/gcc/testsuite/c-c++-common/strub-short-O0-exc.c
> index 1de15342595e4..aaeba2a2159a9 100644
> --- a/gcc/testsuite/c-c++-common/strub-short-O0-exc.c
> +++ b/gcc/testsuite/c-c++-common/strub-short-O0-exc.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O0 -fstrub=strict -fexceptions -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that the expected strub calls are issued. */
>
> diff --git a/gcc/testsuite/c-c++-common/strub-short-O0.c b/gcc/testsuite/c-c++-common/strub-short-O0.c
> index f9209c819004b..30cbdd819f176 100644
> --- a/gcc/testsuite/c-c++-common/strub-short-O0.c
> +++ b/gcc/testsuite/c-c++-common/strub-short-O0.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O0 -fstrub=strict -fno-exceptions -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that the expected strub calls are issued. */
>
> diff --git a/gcc/testsuite/c-c++-common/strub-short-O1.c b/gcc/testsuite/c-c++-common/strub-short-O1.c
> index bed1dcfb54a45..911fdfb6db9a5 100644
> --- a/gcc/testsuite/c-c++-common/strub-short-O1.c
> +++ b/gcc/testsuite/c-c++-common/strub-short-O1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O1 -fstrub=strict -fno-exceptions -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that the expected strub calls are issued. */
>
> diff --git a/gcc/testsuite/c-c++-common/strub-short-O2.c b/gcc/testsuite/c-c++-common/strub-short-O2.c
> index 6bf0071f52b93..9b23ee3ac3312 100644
> --- a/gcc/testsuite/c-c++-common/strub-short-O2.c
> +++ b/gcc/testsuite/c-c++-common/strub-short-O2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O2 -fstrub=strict -fno-exceptions -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that the expected strub calls are issued. */
>
> diff --git a/gcc/testsuite/c-c++-common/strub-short-O3.c b/gcc/testsuite/c-c++-common/strub-short-O3.c
> index 4732f515bf70c..4b3a8f843ea19 100644
> --- a/gcc/testsuite/c-c++-common/strub-short-O3.c
> +++ b/gcc/testsuite/c-c++-common/strub-short-O3.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O3 -fstrub=strict -fno-exceptions -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that the expected strub calls are issued. At -O3 and -Os, we omit
> enter and leave calls within strub contexts, passing on the enclosing
> diff --git a/gcc/testsuite/c-c++-common/strub-short-Os.c b/gcc/testsuite/c-c++-common/strub-short-Os.c
> index 8d6424c479a3a..3627a2406000b 100644
> --- a/gcc/testsuite/c-c++-common/strub-short-Os.c
> +++ b/gcc/testsuite/c-c++-common/strub-short-Os.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-Os -fstrub=strict -fno-exceptions -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that the expected strub calls are issued. At -O3 and -Os, we omit
> enter and leave calls within strub contexts, passing on the enclosing
> diff --git a/gcc/testsuite/c-c++-common/strub-split-stack.c b/gcc/testsuite/c-c++-common/strub-split-stack.c
> new file mode 100644
> index 0000000000000..7a030cdb9e9e6
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/strub-split-stack.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fsplit-stack" } */
> +/* { dg-require-effective-target strub } */
> +/* { dg-require-effective-target split_stack } */
> +
> +void __attribute__ ((__strub__))
> +f () {} /* { dg-message "not eligible|requested" } */
> +
> +void __attribute__ ((__strub__ ("internal")))
> +g () {} /* { dg-message "not eligible|requested" } */
> diff --git a/gcc/testsuite/c-c++-common/strub-strict1.c b/gcc/testsuite/c-c++-common/strub-strict1.c
> index 368522442066e..503eb1734e36f 100644
> --- a/gcc/testsuite/c-c++-common/strub-strict1.c
> +++ b/gcc/testsuite/c-c++-common/strub-strict1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strubm" } */
> +/* { dg-require-effective-target strub } */
>
> static int __attribute__ ((__strub__)) var;
>
> diff --git a/gcc/testsuite/c-c++-common/strub-strict2.c b/gcc/testsuite/c-c++-common/strub-strict2.c
> index b4f2888321821..3bf1aa30b4af1 100644
> --- a/gcc/testsuite/c-c++-common/strub-strict2.c
> +++ b/gcc/testsuite/c-c++-common/strub-strict2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strubm" } */
> +/* { dg-require-effective-target strub } */
>
> static int __attribute__ ((__strub__)) var;
>
> diff --git a/gcc/testsuite/c-c++-common/strub-tail-O1.c b/gcc/testsuite/c-c++-common/strub-tail-O1.c
> index e48e0610e079b..ba4b1623e281a 100644
> --- a/gcc/testsuite/c-c++-common/strub-tail-O1.c
> +++ b/gcc/testsuite/c-c++-common/strub-tail-O1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O1 -fstrub=strict -fno-exceptions -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> #include "strub-tail-O2.c"
>
> diff --git a/gcc/testsuite/c-c++-common/strub-tail-O2.c b/gcc/testsuite/c-c++-common/strub-tail-O2.c
> index 87cda7ab21b16..043813b1de467 100644
> --- a/gcc/testsuite/c-c++-common/strub-tail-O2.c
> +++ b/gcc/testsuite/c-c++-common/strub-tail-O2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-O2 -fstrub=strict -fno-exceptions -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that the expected strub calls are issued.
> Tail calls are short-circuited at -O2+. */
> diff --git a/gcc/testsuite/c-c++-common/strub-unsupported-2.c b/gcc/testsuite/c-c++-common/strub-unsupported-2.c
> new file mode 100644
> index 0000000000000..3586f4f679dfe
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/strub-unsupported-2.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +
> +/* Check that, when strub is not supported (so no dg-required-effective-target
> + strub above), we report when pointers to strub functions are called. This
> + cannot be part of strub-unsupported.c because errors in the strub-mode pass
> + prevent the main strub pass, where errors at calls are detected, from
> + running. */
> +
> +void __attribute__ ((__strub__ ("at-calls"))) (*p) (void);
> +
> +void m () {
> + p (); /* { dg-message "unsupported" "" { target { ! strub } } } */
> +}
> diff --git a/gcc/testsuite/c-c++-common/strub-unsupported-3.c b/gcc/testsuite/c-c++-common/strub-unsupported-3.c
> new file mode 100644
> index 0000000000000..d6fb4c525c4a6
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/strub-unsupported-3.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +
> +/* Check that, when strub is not supported (so no dg-required-effective-target
> + strub above), we report when strub functions that are not defined are
> + called. This cannot be part of strub-unsupported-2.c because errors in the
> + strub-mode pass prevent the main strub pass, where errors at calls are
> + detected, from running. */
> +
> +extern void __attribute__ ((__strub__))
> +s (void); /* { dg-message "not eligible|requested" "" { target { ! strub } } } */
> +
> +extern void __attribute__ ((__strub__ ("internal")))
> +t (void); /* { dg-message "not eligible|requested" "" { target { ! strub } } } */
> +
> +void m () {
> + s ();
> + t ();
> +}
> diff --git a/gcc/testsuite/c-c++-common/strub-unsupported.c b/gcc/testsuite/c-c++-common/strub-unsupported.c
> new file mode 100644
> index 0000000000000..cb5c4049495c4
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/strub-unsupported.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +
> +/* Check that, when strub is not supported (so no dg-required-effective-target
> + strub above), we report when strub functions are defined, and when they're
> + called in ways that would require changes. */
> +
> +void __attribute__ ((__strub__))
> +f (void) {} /* { dg-message "not eligible|requested" "" { target { ! strub } } } */
> +
> +void __attribute__ ((__strub__ ("internal")))
> +g (void) {} /* { dg-message "not eligible|requested" "" { target { ! strub } } } */
> +
> +/* This only gets an error when called, see strub-unsupported-2.c. */
> +void __attribute__ ((__strub__ ("at-calls"))) (*p) (void);
> +
> +/* These too, see strub-unsupported-3.c. */
> +extern void __attribute__ ((__strub__))
> +s (void);
> +
> +extern void __attribute__ ((__strub__ ("internal")))
> +t (void);
> diff --git a/gcc/testsuite/c-c++-common/strub-var1.c b/gcc/testsuite/c-c++-common/strub-var1.c
> index eb6250fd39c90..67014aa5de84a 100644
> --- a/gcc/testsuite/c-c++-common/strub-var1.c
> +++ b/gcc/testsuite/c-c++-common/strub-var1.c
> @@ -1,4 +1,5 @@
> /* { dg-do compile } */
> +/* { dg-require-effective-target strub } */
>
> int __attribute__ ((strub)) x;
> float __attribute__ ((strub)) f;
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-callable1.c b/gcc/testsuite/c-c++-common/torture/strub-callable1.c
> index b5e45ab0525ad..86dbee6746d1b 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-callable1.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-callable1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that strub and non-strub functions can be called from non-strub
> contexts, and that strub and callable functions can be called from strub
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-callable2.c b/gcc/testsuite/c-c++-common/torture/strub-callable2.c
> index 96aa7fe4b07f7..9da120f615645 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-callable2.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-callable2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that impermissible (cross-strub-context) calls are reported. */
>
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-const1.c b/gcc/testsuite/c-c++-common/torture/strub-const1.c
> index 5e956cb1a9b6b..22056713cce4b 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-const1.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-const1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that, along with a strub const function call, we issue an asm
> statement to make sure the watermark passed to it is held in memory before
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-const2.c b/gcc/testsuite/c-c++-common/torture/strub-const2.c
> index 73d650292dfbf..a105c66d7a9c9 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-const2.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-const2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that, along with a strub implicitly-const function call, we issue an
> asm statement to make sure the watermark passed to it is held in memory
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-const3.c b/gcc/testsuite/c-c++-common/torture/strub-const3.c
> index 2584f1f974a58..386200c2784a4 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-const3.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-const3.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that, along with a strub const wrapping call, we issue an asm statement
> to make sure the watermark passed to it is held in memory before the call,
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-const4.c b/gcc/testsuite/c-c++-common/torture/strub-const4.c
> index d819f54ec0230..817e9fa2118b6 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-const4.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-const4.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that, along with a strub implicitly-const wrapping call, we issue an
> asm statement to make sure the watermark passed to it is held in memory
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-data1.c b/gcc/testsuite/c-c++-common/torture/strub-data1.c
> index 7c27a2a1a6dca..132ab63ef733a 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-data1.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-data1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* The pointed-to data enables strubbing if accessed. */
> int __attribute__ ((__strub__)) var;
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-data2.c b/gcc/testsuite/c-c++-common/torture/strub-data2.c
> index e66d903780afd..b660702d26e75 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-data2.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-data2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* The pointer itself is a strub variable, enabling internal strubbing when
> its value is used. */
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-data3.c b/gcc/testsuite/c-c++-common/torture/strub-data3.c
> index 5e08e0e58c658..fc44eef6f8fb5 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-data3.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-data3.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* The pointer itself is a strub variable, that would enable internal strubbing
> if its value was used. Here, it's only overwritten, so no strub. */
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-data4.c b/gcc/testsuite/c-c++-common/torture/strub-data4.c
> index a818e7a38bb5f..85e2f59055b57 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-data4.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-data4.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* The pointer itself is a strub variable, that would enable internal strubbing
> if its value was used. Here, it's only overwritten, so no strub. */
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-data5.c b/gcc/testsuite/c-c++-common/torture/strub-data5.c
> index ddb0b5c0543b0..0a5edac414df1 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-data5.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-data5.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict" } */
> +/* { dg-require-effective-target strub } */
>
> /* It would be desirable to issue at least warnings for these. */
>
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-indcall1.c b/gcc/testsuite/c-c++-common/torture/strub-indcall1.c
> index c165f312f16de..988954e7ed6bc 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-indcall1.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-indcall1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> typedef void __attribute__ ((__strub__)) fntype ();
> fntype (*ptr);
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-indcall2.c b/gcc/testsuite/c-c++-common/torture/strub-indcall2.c
> index 69fcff8d3763d..d3ca91389a700 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-indcall2.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-indcall2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> typedef void __attribute__ ((__strub__)) fntype (int, int);
> fntype (*ptr);
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-indcall3.c b/gcc/testsuite/c-c++-common/torture/strub-indcall3.c
> index ff006224909bd..89b5979cf7b78 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-indcall3.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-indcall3.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> typedef void __attribute__ ((__strub__)) fntype (int, int, ...);
> fntype (*ptr);
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-inlinable1.c b/gcc/testsuite/c-c++-common/torture/strub-inlinable1.c
> index 614b02228ba29..4917dda8826d9 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-inlinable1.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-inlinable1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=relaxed" } */
> +/* { dg-require-effective-target strub } */
>
> inline void __attribute__ ((strub ("internal"), always_inline))
> inl_int_ali (void)
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-inlinable2.c b/gcc/testsuite/c-c++-common/torture/strub-inlinable2.c
> index f9a6b4a16faf8..c45903856d4ff 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-inlinable2.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-inlinable2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=all" } */
> +/* { dg-require-effective-target strub } */
>
> #include "strub-inlinable1.c"
>
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-ptrfn1.c b/gcc/testsuite/c-c++-common/torture/strub-ptrfn1.c
> index b4a7f3992bbaa..b0d6139f0a870 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-ptrfn1.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-ptrfn1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict" } */
> +/* { dg-require-effective-target strub } */
>
> typedef void ft (void);
> typedef void ft2 (int, int);
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-ptrfn2.c b/gcc/testsuite/c-c++-common/torture/strub-ptrfn2.c
> index ef634d351265f..1148c246f2059 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-ptrfn2.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-ptrfn2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=relaxed -Wpedantic" } */
> +/* { dg-require-effective-target strub } */
>
> /* C++ does not warn about the partial incompatibilities.
>
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-ptrfn3.c b/gcc/testsuite/c-c++-common/torture/strub-ptrfn3.c
> index e1f179e160e5c..06a72d86d2c58 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-ptrfn3.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-ptrfn3.c
> @@ -1,6 +1,7 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=relaxed -Wpedantic -fpermissive" } */
> /* { dg-prune-output "command-line option .-fpermissive." } */
> +/* { dg-require-effective-target strub } */
>
> /* See strub-ptrfn2.c. */
>
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-ptrfn4.c b/gcc/testsuite/c-c++-common/torture/strub-ptrfn4.c
> index 70b558afad040..83ea1af7056e7 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-ptrfn4.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-ptrfn4.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=relaxed" } */
> +/* { dg-require-effective-target strub } */
>
> /* This is strub-ptrfn2.c without -Wpedantic.
>
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-pure1.c b/gcc/testsuite/c-c++-common/torture/strub-pure1.c
> index a262a086837b2..2643136f178cc 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-pure1.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-pure1.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that, along with a strub pure function call, we issue an asm statement
> to make sure the watermark passed to it is not assumed to be unchanged. */
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-pure2.c b/gcc/testsuite/c-c++-common/torture/strub-pure2.c
> index 4c4bd50c209a0..8bda129b77dc6 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-pure2.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-pure2.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that, along with a strub implicitly-pure function call, we issue an asm
> statement to make sure the watermark passed to it is not assumed to be
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-pure3.c b/gcc/testsuite/c-c++-common/torture/strub-pure3.c
> index ce195c6b1f1b6..00bcbdd097af8 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-pure3.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-pure3.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that, along with a strub pure wrapping call, we issue an asm statement
> to make sure the watermark passed to it is not assumed to be unchanged. */
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-pure4.c b/gcc/testsuite/c-c++-common/torture/strub-pure4.c
> index 75cd54ccb5b5d..ea7c40e7912b4 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-pure4.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-pure4.c
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that, along with a strub implicitly-pure wrapping call, we issue an asm
> statement to make sure the watermark passed to it is not assumed to be
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-run1.c b/gcc/testsuite/c-c++-common/torture/strub-run1.c
> index 7458b3fb54da5..fdf100428631d 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-run1.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-run1.c
> @@ -1,5 +1,6 @@
> /* { dg-do run } */
> /* { dg-options "-fstrub=strict" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that a non-strub function leaves a string behind in the stack, and that
> equivalent strub functions don't. Avoid the use of red zones by avoiding
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-run2.c b/gcc/testsuite/c-c++-common/torture/strub-run2.c
> index 5d60a7775f4bb..1228a66599721 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-run2.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-run2.c
> @@ -1,5 +1,6 @@
> /* { dg-do run } */
> /* { dg-options "-fstrub=strict" } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that a non-strub function leaves a string behind in the stack, and that
> equivalent strub functions don't. Allow red zones to be used. */
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-run3.c b/gcc/testsuite/c-c++-common/torture/strub-run3.c
> index c2ad710858e87..e5047a988f5bf 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-run3.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-run3.c
> @@ -1,6 +1,7 @@
> /* { dg-do run } */
> /* { dg-options "-fstrub=strict" } */
> /* { dg-require-effective-target alloca } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that a non-strub function leaves a string behind in the stack, and that
> equivalent strub functions don't. */
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-run4.c b/gcc/testsuite/c-c++-common/torture/strub-run4.c
> index 3b36b8e5d68ef..0e84a4bab80fc 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-run4.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-run4.c
> @@ -1,6 +1,7 @@
> /* { dg-do run } */
> /* { dg-options "-fstrub=all" } */
> /* { dg-require-effective-target alloca } */
> +/* { dg-require-effective-target strub } */
>
> /* Check that multi-level, multi-inlined functions still get cleaned up as
> expected, without overwriting temporary stack allocations while they should
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-run4c.c b/gcc/testsuite/c-c++-common/torture/strub-run4c.c
> index 57f9baf758ded..edc98486dc93a 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-run4c.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-run4c.c
> @@ -1,5 +1,6 @@
> /* { dg-do run } */
> /* { dg-options "-fstrub=at-calls" } */
> /* { dg-require-effective-target alloca } */
> +/* { dg-require-effective-target strub } */
>
> #include "strub-run4.c"
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-run4d.c b/gcc/testsuite/c-c++-common/torture/strub-run4d.c
> index 08de3f1c3b17c..487ed08bb6606 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-run4d.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-run4d.c
> @@ -1,6 +1,7 @@
> /* { dg-do run } */
> /* { dg-options "-fstrub=strict" } */
> /* { dg-require-effective-target alloca } */
> +/* { dg-require-effective-target strub } */
>
> #define ATTR_STRUB_AT_CALLS __attribute__ ((__strub__ ("at-calls")))
>
> diff --git a/gcc/testsuite/c-c++-common/torture/strub-run4i.c b/gcc/testsuite/c-c++-common/torture/strub-run4i.c
> index 459f6886c5499..a85447ffabfae 100644
> --- a/gcc/testsuite/c-c++-common/torture/strub-run4i.c
> +++ b/gcc/testsuite/c-c++-common/torture/strub-run4i.c
> @@ -1,5 +1,6 @@
> /* { dg-do run } */
> /* { dg-options "-fstrub=internal" } */
> /* { dg-require-effective-target alloca } */
> +/* { dg-require-effective-target strub } */
>
> #include "strub-run4.c"
> diff --git a/gcc/testsuite/g++.dg/strub-run1.C b/gcc/testsuite/g++.dg/strub-run1.C
> index 0d367fb83d09d..beb8b811f8fca 100644
> --- a/gcc/testsuite/g++.dg/strub-run1.C
> +++ b/gcc/testsuite/g++.dg/strub-run1.C
> @@ -1,5 +1,6 @@
> // { dg-do run }
> // { dg-options "-fstrub=internal" }
> +// { dg-require-effective-target strub }
>
> // Check that we don't get extra copies.
>
> diff --git a/gcc/testsuite/g++.dg/torture/strub-init1.C b/gcc/testsuite/g++.dg/torture/strub-init1.C
> index c226ab10ff651..6ae45fadd70ba 100644
> --- a/gcc/testsuite/g++.dg/torture/strub-init1.C
> +++ b/gcc/testsuite/g++.dg/torture/strub-init1.C
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +// { dg-require-effective-target strub }
>
> extern int __attribute__((__strub__)) initializer ();
>
> diff --git a/gcc/testsuite/g++.dg/torture/strub-init2.C b/gcc/testsuite/g++.dg/torture/strub-init2.C
> index a7911f1fa7212..8f4849c7fde78 100644
> --- a/gcc/testsuite/g++.dg/torture/strub-init2.C
> +++ b/gcc/testsuite/g++.dg/torture/strub-init2.C
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +// { dg-require-effective-target strub }
>
> extern int __attribute__((__strub__)) initializer ();
>
> diff --git a/gcc/testsuite/g++.dg/torture/strub-init3.C b/gcc/testsuite/g++.dg/torture/strub-init3.C
> index 6ebebcd01e8ea..14f28e3c276bd 100644
> --- a/gcc/testsuite/g++.dg/torture/strub-init3.C
> +++ b/gcc/testsuite/g++.dg/torture/strub-init3.C
> @@ -1,5 +1,6 @@
> /* { dg-do compile } */
> /* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
> +// { dg-require-effective-target strub }
>
> extern int __attribute__((__strub__)) initializer ();
>
> diff --git a/gcc/testsuite/gnat.dg/strub_access.adb b/gcc/testsuite/gnat.dg/strub_access.adb
> index 29e6996ecf61c..488a2d64afe31 100644
> --- a/gcc/testsuite/gnat.dg/strub_access.adb
> +++ b/gcc/testsuite/gnat.dg/strub_access.adb
> @@ -1,5 +1,6 @@
> -- { dg-do compile }
> -- { dg-options "-fstrub=relaxed -fdump-ipa-strubm" }
> +-- { dg-require-effective-target strub }
>
> -- The main subprogram doesn't read from the automatic variable, but
> -- being an automatic variable, its presence should be enough for the
> diff --git a/gcc/testsuite/gnat.dg/strub_access1.adb b/gcc/testsuite/gnat.dg/strub_access1.adb
> index dae4706016436..4a8653c4d843f 100644
> --- a/gcc/testsuite/gnat.dg/strub_access1.adb
> +++ b/gcc/testsuite/gnat.dg/strub_access1.adb
> @@ -1,5 +1,6 @@
> -- { dg-do compile }
> -- { dg-options "-fstrub=relaxed" }
> +-- { dg-require-effective-target strub }
>
> -- Check that we reject 'Access of a strub variable whose type does
> -- not carry a strub modifier.
> diff --git a/gcc/testsuite/gnat.dg/strub_attr.adb b/gcc/testsuite/gnat.dg/strub_attr.adb
> index 10445d7cf8451..eb7826dc990f4 100644
> --- a/gcc/testsuite/gnat.dg/strub_attr.adb
> +++ b/gcc/testsuite/gnat.dg/strub_attr.adb
> @@ -1,5 +1,6 @@
> -- { dg-do compile }
> -- { dg-options "-fstrub=strict -fdump-ipa-strubm -fdump-ipa-strub" }
> +-- { dg-require-effective-target strub }
>
> package body Strub_Attr is
> E : exception;
> diff --git a/gcc/testsuite/gnat.dg/strub_disp.adb b/gcc/testsuite/gnat.dg/strub_disp.adb
> index 3dbcc4a357cba..f23d4675def38 100644
> --- a/gcc/testsuite/gnat.dg/strub_disp.adb
> +++ b/gcc/testsuite/gnat.dg/strub_disp.adb
> @@ -1,4 +1,5 @@
> -- { dg-do compile }
> +-- { dg-require-effective-target strub }
>
> procedure Strub_Disp is
> package Foo is
> diff --git a/gcc/testsuite/gnat.dg/strub_disp1.adb b/gcc/testsuite/gnat.dg/strub_disp1.adb
> index 09756a74b7d81..9c4c7f696371d 100644
> --- a/gcc/testsuite/gnat.dg/strub_disp1.adb
> +++ b/gcc/testsuite/gnat.dg/strub_disp1.adb
> @@ -1,5 +1,6 @@
> -- { dg-do compile }
> -- { dg-options "-fdump-ipa-strub" }
> +-- { dg-require-effective-target strub }
>
> -- Check that at-calls dispatching calls are transformed.
>
> diff --git a/gcc/testsuite/gnat.dg/strub_ind.adb b/gcc/testsuite/gnat.dg/strub_ind.adb
> index da56acaa957d2..613db69305e05 100644
> --- a/gcc/testsuite/gnat.dg/strub_ind.adb
> +++ b/gcc/testsuite/gnat.dg/strub_ind.adb
> @@ -1,5 +1,6 @@
> -- { dg-do compile }
> -- { dg-options "-fstrub=strict" }
> +-- { dg-require-effective-target strub }
>
> -- This is essentially the same test as strub_attr.adb,
> -- but applying attributes to access types as well.
> diff --git a/gcc/testsuite/gnat.dg/strub_ind1.adb b/gcc/testsuite/gnat.dg/strub_ind1.adb
> index 825e395e6819c..245b0a830f691 100644
> --- a/gcc/testsuite/gnat.dg/strub_ind1.adb
> +++ b/gcc/testsuite/gnat.dg/strub_ind1.adb
> @@ -1,5 +1,6 @@
> -- { dg-do compile }
> -- { dg-options "-fstrub=strict -fdump-ipa-strubm" }
> +-- { dg-require-effective-target strub }
>
> -- This is essentially the same test as strub_attr.adb,
> -- but with an explicit conversion.
> diff --git a/gcc/testsuite/gnat.dg/strub_ind2.adb b/gcc/testsuite/gnat.dg/strub_ind2.adb
> index e918b39263117..b9bfe50e9296e 100644
> --- a/gcc/testsuite/gnat.dg/strub_ind2.adb
> +++ b/gcc/testsuite/gnat.dg/strub_ind2.adb
> @@ -1,5 +1,6 @@
> -- { dg-do compile }
> -- { dg-options "-fstrub=strict" }
> +-- { dg-require-effective-target strub }
>
> -- This is essentially the same test as strub_attr.adb,
> -- but with an explicit conversion.
> diff --git a/gcc/testsuite/gnat.dg/strub_intf.adb b/gcc/testsuite/gnat.dg/strub_intf.adb
> index 8f0212a75866f..f43854705d073 100644
> --- a/gcc/testsuite/gnat.dg/strub_intf.adb
> +++ b/gcc/testsuite/gnat.dg/strub_intf.adb
> @@ -1,4 +1,5 @@
> -- { dg-do compile }
> +-- { dg-require-effective-target strub }
>
> -- Check that strub mode mismatches between overrider and overridden
> -- subprograms are reported.
> diff --git a/gcc/testsuite/gnat.dg/strub_intf1.adb b/gcc/testsuite/gnat.dg/strub_intf1.adb
> index bf77321cef790..7a38a4c49ba8d 100644
> --- a/gcc/testsuite/gnat.dg/strub_intf1.adb
> +++ b/gcc/testsuite/gnat.dg/strub_intf1.adb
> @@ -1,5 +1,6 @@
> -- { dg-do compile }
> -- { dg-options "-fdump-ipa-strub" }
> +-- { dg-require-effective-target strub }
>
> -- Check that at-calls dispatching calls to interfaces are transformed.
>
> diff --git a/gcc/testsuite/gnat.dg/strub_intf2.adb b/gcc/testsuite/gnat.dg/strub_intf2.adb
> index e8880dbc43730..7992b7344fb87 100644
> --- a/gcc/testsuite/gnat.dg/strub_intf2.adb
> +++ b/gcc/testsuite/gnat.dg/strub_intf2.adb
> @@ -1,4 +1,5 @@
> -- { dg-do compile }
> +-- { dg-require-effective-target strub }
>
> -- Check that strub mode mismatches between overrider and overridden
> -- subprograms are reported even when the overriders for an
> diff --git a/gcc/testsuite/gnat.dg/strub_renm.adb b/gcc/testsuite/gnat.dg/strub_renm.adb
> index 217367e712d82..abfb120b51468 100644
> --- a/gcc/testsuite/gnat.dg/strub_renm.adb
> +++ b/gcc/testsuite/gnat.dg/strub_renm.adb
> @@ -1,4 +1,5 @@
> -- { dg-do compile }
> +-- { dg-require-effective-target strub }
>
> procedure Strub_Renm is
> procedure P (X : Integer);
> diff --git a/gcc/testsuite/gnat.dg/strub_renm1.adb b/gcc/testsuite/gnat.dg/strub_renm1.adb
> index a11adbfb5a9d6..68d3230b5356c 100644
> --- a/gcc/testsuite/gnat.dg/strub_renm1.adb
> +++ b/gcc/testsuite/gnat.dg/strub_renm1.adb
> @@ -1,5 +1,6 @@
> -- { dg-do compile }
> -- { dg-options "-fstrub=relaxed -fdump-ipa-strub" }
> +-- { dg-require-effective-target strub }
>
> procedure Strub_Renm1 is
> V : Integer := 0;
> diff --git a/gcc/testsuite/gnat.dg/strub_renm2.adb b/gcc/testsuite/gnat.dg/strub_renm2.adb
> index c488c20826fdb..3cb81ea03f763 100644
> --- a/gcc/testsuite/gnat.dg/strub_renm2.adb
> +++ b/gcc/testsuite/gnat.dg/strub_renm2.adb
> @@ -1,5 +1,6 @@
> -- { dg-do compile }
> -- { dg-options "-fstrub=strict -fdump-ipa-strub" }
> +-- { dg-require-effective-target strub }
>
> procedure Strub_Renm2 is
> V : Integer := 0;
> diff --git a/gcc/testsuite/gnat.dg/strub_var.adb b/gcc/testsuite/gnat.dg/strub_var.adb
> index 3d158de28031f..7c6affa06d4ab 100644
> --- a/gcc/testsuite/gnat.dg/strub_var.adb
> +++ b/gcc/testsuite/gnat.dg/strub_var.adb
> @@ -1,5 +1,6 @@
> -- { dg-do compile }
> -- { dg-options "-fstrub=strict -fdump-ipa-strubm" }
> +-- { dg-require-effective-target strub }
>
> -- We don't read from the automatic variable, but being an automatic
> -- variable, its presence should be enough for the procedure to get
> diff --git a/gcc/testsuite/gnat.dg/strub_var1.adb b/gcc/testsuite/gnat.dg/strub_var1.adb
> index 6a504e09198b6..64b7e65fe9b0f 100644
> --- a/gcc/testsuite/gnat.dg/strub_var1.adb
> +++ b/gcc/testsuite/gnat.dg/strub_var1.adb
> @@ -1,4 +1,5 @@
> -- { dg-do compile }
> +-- { dg-require-effective-target strub }
>
> with Strub_Attr;
> procedure Strub_Var1 is
> diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
> index 3fcce6be49d6f..40a60c198cfe8 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -1302,6 +1302,13 @@ proc check_stack_check_available { stack_kind } {
> } "$stack_opt"]
> }
>
> +# Return 1 if the target supports stack scrubbing.
> +proc check_effective_target_strub {} {
> + return [check_no_compiler_messages strub assembly {
> + void __attribute__ ((__strub__)) fn (void) {}
> + } ""]
> +}
> +
> # Return 1 if compilation with -freorder-blocks-and-partition is error-free
> # for trivial code, 0 otherwise. As some targets (ARM for example) only
> # warn when -fprofile-use is also supplied we test that combination too.
> diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
> index d8163c5af9903..3f77283490ef6 100644
> --- a/libgcc/Makefile.in
> +++ b/libgcc/Makefile.in
> @@ -434,7 +434,7 @@ LIB2ADD += enable-execute-stack.c
> LIB2ADD += $(srcdir)/hardcfr.c
>
> # Stack scrubbing infrastructure.
> -LIB2ADD += $(srcdir)/strub.c
> +@HAVE_STRUB_SUPPORT@LIB2ADD += $(srcdir)/strub.c
>
> # While emutls.c has nothing to do with EH, it is in LIB2ADDEH*
> # instead of LIB2ADD because that's the way to be sure on some targets
> diff --git a/libgcc/configure b/libgcc/configure
> index cf149209652e3..567158955a329 100755
> --- a/libgcc/configure
> +++ b/libgcc/configure
> @@ -593,6 +593,7 @@ asm_hidden_op
> extra_parts
> cpu_type
> get_gcc_base_ver
> +HAVE_STRUB_SUPPORT
> thread_header
> tm_defines
> tm_file
> @@ -5702,6 +5703,31 @@ esac
>
>
>
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for strub support" >&5
> +$as_echo_n "checking for strub support... " >&6; }
> +if ${libgcc_cv_strub_support+:} false; then :
> + $as_echo_n "(cached) " >&6
> +else
> + cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h. */
> +void __attribute__ ((__strub__)) fn (void) {}
> +_ACEOF
> +if ac_fn_c_try_compile "$LINENO"; then :
> + libgcc_cv_strub_support=yes
> +else
> + libgcc_cv_strub_support=no
> +fi
> +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
> +fi
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_strub_support" >&5
> +$as_echo "$libgcc_cv_strub_support" >&6; }
> +if test "x$libgcc_cv_strub_support" != xno; then
> + HAVE_STRUB_SUPPORT=
> +else
> + HAVE_STRUB_SUPPORT='# '
> +fi
> +
> +
> # Determine what GCC version number to use in filesystem paths.
>
> get_gcc_base_ver="cat"
> diff --git a/libgcc/configure.ac b/libgcc/configure.ac
> index 2fc9d5d7c93e9..9c0e415501a80 100644
> --- a/libgcc/configure.ac
> +++ b/libgcc/configure.ac
> @@ -694,6 +694,19 @@ AC_SUBST(tm_defines)
> # Map from thread model to thread header.
> GCC_AC_THREAD_HEADER([$target_thread_file])
>
> +AC_CACHE_CHECK([for strub support],
> + [libgcc_cv_strub_support],
> + [AC_COMPILE_IFELSE(
> + [AC_LANG_SOURCE([void __attribute__ ((__strub__)) fn (void) {}])],
> + [libgcc_cv_strub_support=yes],
> + [libgcc_cv_strub_support=no])])
> +if test "x$libgcc_cv_strub_support" != xno; then
> + HAVE_STRUB_SUPPORT=
> +else
> + HAVE_STRUB_SUPPORT='# '
> +fi
> +AC_SUBST(HAVE_STRUB_SUPPORT)
> +
> # Determine what GCC version number to use in filesystem paths.
> GCC_BASE_VER
>
>
>
> --
> Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/
> Free Software Activist GNU Toolchain Engineer
> More tolerance and less prejudice are key for inclusion and diversity
> Excluding neuro-others for not behaving ""normal"" is *not* inclusive
next prev parent reply other threads:[~2023-12-07 7:28 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <ormtqpsbuc.fsf@lxoliva.fsfla.org>
2021-09-09 7:11 ` [PATCH] strub: machine-independent stack scrubbing Alexandre Oliva
2022-07-29 6:16 ` [PATCH v2 00/10] Introduce " Alexandre Oliva
2022-07-29 6:24 ` [PATCH v2 01/10] Introduce strub: documentation, and new command-line options Alexandre Oliva
2022-07-29 6:25 ` [PATCH v2 02/10] Introduce strub: torture tests for C and C++ Alexandre Oliva
2022-08-09 13:34 ` Alexandre Oliva
2022-07-29 6:25 ` [PATCH v2 03/10] Introduce strub: non-torture " Alexandre Oliva
2022-07-29 6:26 ` [PATCH v2 04/10] Introduce strub: tests for C++ and Ada Alexandre Oliva
2022-07-29 6:26 ` [PATCH v2 05/10] Introduce strub: builtins and runtime Alexandre Oliva
2022-07-29 6:27 ` [PATCH v2 06/10] Introduce strub: attributes Alexandre Oliva
2022-07-29 6:28 ` [PATCH v2 07/10] Introduce strub: infrastructure interfaces and adjustments Alexandre Oliva
2022-07-29 6:28 ` [PATCH v2 08/10] Introduce strub: strub modes Alexandre Oliva
2022-07-29 6:30 ` [PATCH v2 09/10] Introduce strub: strubm (mode assignment) pass Alexandre Oliva
2022-07-29 6:34 ` [PATCH v2 10/10] Introduce strub: strub pass Alexandre Oliva
2022-07-29 6:36 ` [PATCH v2 00/10] Introduce strub: machine-independent stack scrubbing Alexandre Oliva
2022-10-10 8:48 ` Richard Biener
2022-10-11 11:57 ` Alexandre Oliva
2022-10-11 11:59 ` Richard Biener
2022-10-11 13:33 ` Alexandre Oliva
2022-10-13 11:38 ` Richard Biener
2022-10-13 13:15 ` Alexandre Oliva
2023-06-16 6:09 ` [PATCH v3] " Alexandre Oliva
2023-06-27 21:28 ` Qing Zhao
2023-06-28 8:20 ` Alexandre Oliva
2023-10-20 6:03 ` [PATCH v4] " Alexandre Oliva
2023-10-26 6:15 ` Alexandre Oliva
2023-11-20 12:40 ` Alexandre Oliva
2023-11-22 14:14 ` Richard Biener
2023-11-23 10:56 ` Alexandre Oliva
2023-11-23 12:05 ` Richard Biener
2023-11-29 8:53 ` Alexandre Oliva
2023-11-29 12:48 ` Richard Biener
2023-11-30 4:13 ` Alexandre Oliva
2023-11-30 12:00 ` Richard Biener
2023-12-02 17:56 ` [PATCH v5] " Alexandre Oliva
2023-12-05 6:25 ` Alexandre Oliva
2023-12-06 1:04 ` Alexandre Oliva
2023-12-05 9:01 ` Richard Biener
2023-12-06 8:36 ` Causes to nvptx bootstrap fail: " Tobias Burnus
2023-12-06 11:32 ` Thomas Schwinge
2023-12-06 22:12 ` Alexandre Oliva
2023-12-07 3:33 ` [PATCH] strub: enable conditional support Alexandre Oliva
2023-12-07 7:24 ` Richard Biener [this message]
2023-12-07 16:44 ` Thomas Schwinge
2023-12-07 17:52 ` [PATCH] Alexandre Oliva
2023-12-08 6:46 ` [PATCH] Richard Biener
2023-12-08 9:33 ` [PATCH] strub: skip emutls after strubm errors Thomas Schwinge
2023-12-10 9:16 ` FX Coudert
2023-12-07 7:21 ` Causes to nvptx bootstrap fail: [PATCH v5] Introduce strub: machine-independent stack scrubbing Richard Biener
2023-12-06 10:22 ` Jan Hubicka
2023-12-07 21:19 ` Alexandre Oliva
2023-12-07 21:39 ` Alexandre Oliva
2023-12-09 2:08 ` [PATCH] strub: add note on attribute access Alexandre Oliva
2023-12-11 7:26 ` Richard Biener
2023-12-12 14:21 ` Jan Hubicka
2023-12-11 8:40 ` [PATCH] testsuite: Disable -fstack-protector* for some strub tests Jakub Jelinek
2023-12-11 8:59 ` Richard Biener
2023-12-20 8:15 ` [PATCH FYI] www: new AdaCore-contributed hardening features in gcc 13 and 14 Alexandre Oliva
2023-11-30 5:04 ` [PATCH v4] Introduce strub: machine-independent stack scrubbing Alexandre Oliva
2023-11-30 11:56 ` Richard Biener
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAFiYyc3vw5EQGgXUq3hUyG-MocrSVjGrdCh+pp6UQ-x5ER5A3g@mail.gmail.com \
--to=richard.guenther@gmail.com \
--cc=craig.blackmore@embecosm.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=graham.markall@embecosm.com \
--cc=hubicka@ucw.cz \
--cc=jakub@redhat.com \
--cc=jeffreyalaw@gmail.com \
--cc=jeremy.bennett@embecosm.com \
--cc=mjambor@suse.cz \
--cc=oliva@adacore.com \
--cc=tdevries@suse.de \
--cc=thomas@codesourcery.com \
--cc=tobias@codesourcery.com \
--cc=wilson@tuliptree.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).