From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from esa3.mentor.iphmx.com (esa3.mentor.iphmx.com [68.232.137.180]) by sourceware.org (Postfix) with ESMTPS id 97D523861828 for ; Thu, 7 Dec 2023 16:45:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 97D523861828 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 97D523861828 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=68.232.137.180 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701967506; cv=none; b=XUc357mnKWI5AWUMa7ZDQzrWUmKBWDaDLMhbGHf2XCo7/HTeoB7K+8FgfRcmHRNQva9/lGYUTkifXS9WQHboGextmhVeGDZn14LxbDc4Z4WHSEzuSdeEZI9RA276hQznY37hrssJemfax4qrYD4xjJwFaSUp/AlRKa69Z/rfdfQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701967506; c=relaxed/simple; bh=GtDAB6WCTiG8hFDVMCR8VRaKtma14D2+CyqKqceRrso=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=NSPu+BEmHpCrtCw1JAQPBEYRIoMDRZIfdtux4h54mMbs/ozQ83JNtErpbP23EsC5w3X9ZCDGVpxHsp/D9tr2e981hL5TTgLArWD9L6O3RmTepdCju8NOnTQTGZ0nmmdNNM4YZCVwxb67mBnACmKlj1ue+lDxKiywYAQy6qoRu9M= ARC-Authentication-Results: i=1; server2.sourceware.org X-CSE-ConnectionGUID: rWj/BB4HSkCbk5oB3+mR0A== X-CSE-MsgGUID: E80aHRIBSSmj2FysHfDmQw== X-IronPort-AV: E=Sophos;i="6.04,258,1695715200"; d="scan'208";a="24738619" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa3.mentor.iphmx.com with ESMTP; 07 Dec 2023 08:44:56 -0800 IronPort-SDR: GFhBeOCQ6fnVpFzsXqVJMrsfbDYPuUxiP1+ngE3ZyU3i8mjERG2NSge7IJdFex2+jK2CbblnHZ cWIWhhl7SWX2i3HGzyJVBq5mKYMWgegTn9G/GMaGWWXfwTLe1H0haZbtJ19ZFZ7jYhRAvkZJVk AJ6zq1A2P08q7Sji+8m37TWq1/Uq+/FyQIEtbUKr8of/7cVo4Cve8mL3rcl2k9Q9vEkqWTkvnZ C+ZuBJIYMyTbh9oku6VatVu+vBym8hQY2h12xDCiEIo5S9yuu/ccaqUZtitDf8toMQ0+bLTgrx g34= From: Thomas Schwinge To: Alexandre Oliva CC: Tobias Burnus , Richard Biener , , Jeremy Bennett , Craig Blackmore , Graham Markall , Martin Jambor , "Jan Hubicka" , Jim Wilson , Jeff Law , Jakub Jelinek , Tom de Vries Subject: Re: [PATCH] strub: enable conditional support In-Reply-To: References: <87lea7sh0h.fsf@euler.schwinge.homeip.net> User-Agent: Notmuch/0.29.3+94~g74c3f1b (https://notmuchmail.org) Emacs/28.2 (x86_64-pc-linux-gnu) Date: Thu, 7 Dec 2023 17:44:45 +0100 Message-ID: <8734wet11e.fsf@euler.schwinge.homeip.net> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-10.mgc.mentorg.com (139.181.222.10) To svr-ies-mbx-10.mgc.mentorg.com (139.181.222.10) X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00,GIT_PATCH_0,HEADER_FROM_DIFFERENT_DOMAINS,KAM_DMARC_STATUS,SPF_HELO_PASS,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE,WEIRD_PORT autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi Alexandre! Thank you for looking into this so promptly! On 2023-12-07T00:33:59-0300, Alexandre Oliva wrote: > On Dec 6, 2023, Alexandre Oliva 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=3Ddisable, > 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? GCC/nvptx target again builds as before, and testing just completed: as expected, the "strub" test cases generally UNSUPPORTED, just something's wrong with two of the 'c-c++-common/strub-unsupported*.c' test cases: +PASS: c-c++-common/strub-unsupported-2.c -Wc++-compat (test for war= nings, line 12) +PASS: c-c++-common/strub-unsupported-2.c -Wc++-compat (test for exce= ss errors) +FAIL: c-c++-common/strub-unsupported-3.c -Wc++-compat (internal comp= iler error: in verify_curr_properties, at passes.cc:2198) +PASS: c-c++-common/strub-unsupported-3.c -Wc++-compat (test for war= nings, line 10) +PASS: c-c++-common/strub-unsupported-3.c -Wc++-compat (test for war= nings, line 13) +FAIL: c-c++-common/strub-unsupported-3.c -Wc++-compat (test for exce= ss errors) +FAIL: c-c++-common/strub-unsupported.c -Wc++-compat (internal compil= er error: in verify_curr_properties, at passes.cc:2198) +PASS: c-c++-common/strub-unsupported.c -Wc++-compat (test for warni= ngs, line 8) +PASS: c-c++-common/strub-unsupported.c -Wc++-compat (test for warni= ngs, line 11) +FAIL: c-c++-common/strub-unsupported.c -Wc++-compat (test for excess= errors) Similar for C++ testing. The ICE is: during IPA pass: emutls [...]/source-gcc/gcc/testsuite/c-c++-common/strub-unsupported-3.c:18:1:= internal compiler error: in verify_curr_properties, at passes.cc:2198 0x10b671db verify_curr_properties [...]/source-gcc/gcc/passes.cc:2198 0x10b67ca3 do_per_function [...]/source-gcc/gcc/passes.cc:1694 I'm certainly fine if we deal with that one incrementally. I'll answer your (quite right) '__builtin_{frame,stack}_address' remarks (earlier email) separately, later on. Gr=C3=BC=C3=9Fe Thomas > 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 =3D 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{libgfortra= n}. > @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 functi= on > +or type, otherwise return false. The default implementation always retu= rns > +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 =3D false, > + location_t loc =3D UNKNOWN_LOCATION) > +{ > + bool result =3D true; > + > + if (!targetm.have_strub_support_for (t)) > + { > + result =3D false; > + > + if (!report) > + return result; > + > + if (DECL_P (t)) > + sorry_at (DECL_SOURCE_LOCATION (t), > + "%qD is not eligible for %" > + " on the target system", t); > + else > + sorry_at (loc, > + "unsupported % call" > + " on the target system"); > + } > + > + return result; > +} > + > /* Return TRUE iff NODE is potentially eligible for any strub-enabled mo= de, and > optionally REPORT the reasons for ineligibility. */ > > static inline bool > can_strub_p (cgraph_node *node, bool report =3D false) > { > - bool result =3D true; > + bool result =3D 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 =3D false; > + > + if (!report) > + return result; > + > + sorry_at (DECL_SOURCE_LOCATION (node->decl), > + "%qD is not eligible for %" > + " because %<-fsplit-stack%> is enabled", > + node->decl); > + } > + > if (lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl))) > { > result =3D 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)= ) > =3D=3D get_pwmt ()))); > > + tree tsup; > + if (!(tsup =3D gimple_call_fndecl (ocall))) > + tsup =3D 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 water= mark > pointer, and omit the enter and leave calls around the modified cal= l, 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 implementatio= n 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 func= tion\n\ > +or type, otherwise return false. The default implementation always retu= rns\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=3Dstrict -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=3Dstrict -fdump-rtl-expand" } */ > +/* { dg-require-effective-target strub } */ > > /* At -O1, without -fno-inline, we fully expand enter, but neither updat= e 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=3Dstrict -fdump-rtl-expand" } */ > +/* { dg-require-effective-target strub } */ > > /* At -O2, without -fno-inline, we fully expand enter and update, and ad= d 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=3Dstrict -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=3Dstrict -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=3Dstrict -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=3Dstrict -fdump-rtl-expand" } */ > +/* { dg-require-effective-target strub } */ > > /* At -Og, without -fno-inline, we fully expand enter, but neither updat= e 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=3Dstrict -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 savi= ng 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=3Dall -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=3Dall -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=3Dstrict" } */ > +/* { 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=3Dstrict" } */ > +/* { 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=3Dstrict" } */ > +/* { 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=3Dstrict -fdump-ipa-strubm" } */ > +/* { dg-require-effective-target strub } */ > > /* Check that implicit enabling of strub mode selects internal strub whe= n 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=3Dat-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=3Dat-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 in= line, > force_output is set for static non-inline functions when not optimizi= ng, 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=3Dstrict -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=3Dstrict -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=3Dstrict -O3" } */ > +/* { dg-require-effective-target strub } */ > > /* Check that a strub function called by another strub function defers t= he > 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=3Dstrict -Os" } */ > +/* { dg-require-effective-target strub } */ > > /* Check that a strub function called by another strub function defers t= he > 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=3Dinternal -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=3Dinternal -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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > #include > > 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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > #include > > 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=3Dstrict -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 th= eir > 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=3Drelaxed -fdump-ipa-strubm -fdump-ipa-strub" }= */ > +/* { dg-require-effective-target strub } */ > > /* The difference between relaxed and strict in this case is that we acc= ept 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=3Drelaxed -fdump-ipa-strubm -fdump-ipa-strub" }= */ > +/* { dg-require-effective-target strub } */ > > /* The difference between relaxed and strict in this case is that we acc= ept the > call from one internal-strub function to another. */ > diff --git a/gcc/testsuite/c-c++-common/strub-short-O0-exc.c b/gcc/testsu= ite/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=3Dstrict -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=3Dstrict -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=3Dstrict -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=3Dstrict -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=3Dstrict -fno-exceptions -fdump-ipa-strub" = } */ > +/* { dg-require-effective-target strub } */ > > /* Check that the expected strub calls are issued. At -O3 and -Os, we o= mit > 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=3Dstrict -fno-exceptions -fdump-ipa-strub" = } */ > +/* { dg-require-effective-target strub } */ > > /* Check that the expected strub calls are issued. At -O3 and -Os, we o= mit > 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/testsui= te/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=3Dstrict -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=3Dstrict -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=3Dstrict -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=3Dstrict -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/tests= uite/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-mod= e 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/tests= uite/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 ar= e > + 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/testsui= te/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 th= ey're > + called in ways that would require changes. */ > + > +void __attribute__ ((__strub__)) > +f (void) {} /* { dg-message "not eligible|requested" "" { target { ! str= ub } } } */ > + > +void __attribute__ ((__strub__ ("internal"))) > +g (void) {} /* { dg-message "not eligible|requested" "" { target { ! str= ub } } } */ > + > +/* 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/t= estsuite/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=3Dstrict" } */ > +/* { 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 st= rub > diff --git a/gcc/testsuite/c-c++-common/torture/strub-callable2.c b/gcc/t= estsuite/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=3Dstrict" } */ > +/* { 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/test= suite/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=3Dstrict -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 b= efore > diff --git a/gcc/testsuite/c-c++-common/torture/strub-const2.c b/gcc/test= suite/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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > /* Check that, along with a strub implicitly-const function call, we iss= ue an > asm statement to make sure the watermark passed to it is held in memo= ry > diff --git a/gcc/testsuite/c-c++-common/torture/strub-const3.c b/gcc/test= suite/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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > /* Check that, along with a strub const wrapping call, we issue an asm s= tatement > 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/test= suite/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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > /* Check that, along with a strub implicitly-const wrapping call, we iss= ue an > asm statement to make sure the watermark passed to it is held in memo= ry > diff --git a/gcc/testsuite/c-c++-common/torture/strub-data1.c b/gcc/tests= uite/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=3Dstrict -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/tests= uite/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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > /* The pointer itself is a strub variable, enabling internal strubbing w= hen > its value is used. */ > diff --git a/gcc/testsuite/c-c++-common/torture/strub-data3.c b/gcc/tests= uite/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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > /* The pointer itself is a strub variable, that would enable internal st= rubbing > 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/tests= uite/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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > /* The pointer itself is a strub variable, that would enable internal st= rubbing > 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/tests= uite/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=3Dstrict" } */ > +/* { 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/te= stsuite/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=3Dstrict -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/te= stsuite/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=3Dstrict -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/te= stsuite/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=3Dstrict -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=3Drelaxed" } */ > +/* { 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=3Dall" } */ > +/* { dg-require-effective-target strub } */ > > #include "strub-inlinable1.c" > > diff --git a/gcc/testsuite/c-c++-common/torture/strub-ptrfn1.c b/gcc/test= suite/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=3Dstrict" } */ > +/* { 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/test= suite/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=3Drelaxed -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/test= suite/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=3Drelaxed -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/test= suite/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=3Drelaxed" } */ > +/* { 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/tests= uite/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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > /* Check that, along with a strub pure function call, we issue an asm st= atement > to make sure the watermark passed to it is not assumed to be unchange= d. */ > diff --git a/gcc/testsuite/c-c++-common/torture/strub-pure2.c b/gcc/tests= uite/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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > /* Check that, along with a strub implicitly-pure function call, we issu= e an asm > statement to make sure the watermark passed to it is not assumed to b= e > diff --git a/gcc/testsuite/c-c++-common/torture/strub-pure3.c b/gcc/tests= uite/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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > /* Check that, along with a strub pure wrapping call, we issue an asm st= atement > to make sure the watermark passed to it is not assumed to be unchange= d. */ > diff --git a/gcc/testsuite/c-c++-common/torture/strub-pure4.c b/gcc/tests= uite/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=3Dstrict -fdump-ipa-strub" } */ > +/* { dg-require-effective-target strub } */ > > /* Check that, along with a strub implicitly-pure wrapping call, we issu= e an asm > statement to make sure the watermark passed to it is not assumed to b= e > diff --git a/gcc/testsuite/c-c++-common/torture/strub-run1.c b/gcc/testsu= ite/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=3Dstrict" } */ > +/* { 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 avoi= ding > diff --git a/gcc/testsuite/c-c++-common/torture/strub-run2.c b/gcc/testsu= ite/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=3Dstrict" } */ > +/* { 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/testsu= ite/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=3Dstrict" } */ > /* { 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/testsu= ite/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=3Dall" } */ > /* { 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/tests= uite/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=3Dat-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/tests= uite/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=3Dstrict" } */ > /* { 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/tests= uite/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=3Dinternal" } */ > /* { 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/str= ub-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=3Dinternal" } > +// { 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=3Dstrict -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=3Dstrict -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=3Dstrict -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=3Drelaxed -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=3Drelaxed" } > +-- { 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=3Dstrict -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.d= g/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=3Dstrict" } > +-- { 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=3Dstrict -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=3Dstrict" } > +-- { 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.d= g/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.d= g/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.d= g/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=3Drelaxed -fdump-ipa-strub" } > +-- { dg-require-effective-target strub } > > procedure Strub_Renm1 is > V : Integer :=3D 0; > diff --git a/gcc/testsuite/gnat.dg/strub_renm2.adb b/gcc/testsuite/gnat.d= g/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=3Dstrict -fdump-ipa-strub" } > +-- { dg-require-effective-target strub } > > procedure Strub_Renm2 is > V : Integer :=3D 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=3Dstrict -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/ta= rget-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-f= ree > # 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 +=3D enable-execute-stack.c > LIB2ADD +=3D $(srcdir)/hardcfr.c > > # Stack scrubbing infrastructure. > -LIB2ADD +=3D $(srcdir)/strub.c > +@HAVE_STRUB_SUPPORT@LIB2ADD +=3D $(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=3Dyes > +else > + libgcc_cv_strub_support=3Dno > +fi > +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext > +fi > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_strub_suppor= t" >&5 > +$as_echo "$libgcc_cv_strub_support" >&6; } > +if test "x$libgcc_cv_strub_support" !=3D xno; then > + HAVE_STRUB_SUPPORT=3D > +else > + HAVE_STRUB_SUPPORT=3D'# ' > +fi > + > + > # Determine what GCC version number to use in filesystem paths. > > get_gcc_base_ver=3D"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=3Dyes], > + [libgcc_cv_strub_support=3Dno])]) > +if test "x$libgcc_cv_strub_support" !=3D xno; then > + HAVE_STRUB_SUPPORT=3D > +else > + HAVE_STRUB_SUPPORT=3D'# ' > +fi > +AC_SUBST(HAVE_STRUB_SUPPORT) > + > # Determine what GCC version number to use in filesystem paths. > GCC_BASE_VER > ----------------- Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstra=C3=9Fe 201= , 80634 M=C3=BCnchen; Gesellschaft mit beschr=C3=A4nkter Haftung; Gesch=C3= =A4ftsf=C3=BChrer: Thomas Heurung, Frank Th=C3=BCrauf; Sitz der Gesellschaf= t: M=C3=BCnchen; Registergericht M=C3=BCnchen, HRB 106955