From: Alexandre Oliva Date: Thu, 7 Dec 2023 15:58:20 +0000 (-0300) Subject: strub: enable conditional support X-Git-Tag: basepoints/gcc-15~3864 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f908368d2cb50b26c4557df6b37bc13a3723ef49;p=thirdparty%2Fgcc.git strub: enable conditional support 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. 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 * c-c++-common/strub-split-stack.c: New. * c-c++-common/strub-unsupported.c: New. * c-c++-common/strub-unsupported-2.c: New. * c-c++-common/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. --- diff --git a/gcc/config/nvptx/nvptx.cc b/gcc/config/nvptx/nvptx.cc index ae20802c8799..3fb1deb70fda 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 c99090268541..26a7e9c35070 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 89a1735dd799..768ada0af522 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 ebc1d3de5caa..4fe0805394ea 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 293bec132b88..2afb7a455751 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 %" + " 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 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 %" + " 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 52b83e091b94..08218f3a42ad 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 c7a79a6ea0d8..f0a3f7b4c6f9 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 96285c975d98..50403426b18f 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 8edc0d8aa132..37e02998e318 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 c6d900cf3c45..905e2c6b2ffc 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 33ee465e51cb..3bbf132bdf1e 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 2936f82079e1..c46fce38e5c9 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 479746e57d87..3b8eb19765cd 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 2241d4ea07f2..8cfb253d6764 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 a322bcc5da60..2037f681f297 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 db60026d0e08..c026e7d9d289 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 2f462adc1efe..3edc89c54eea 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 a5d7551f5da5..838fc7527345 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 64422a0d1e88..0206e4d930e7 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 15ffaa031b89..e82504728b2c 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 b70843b4215a..a20acc0a48a5 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 97a3988a6b92..7915b33a39a0 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 3d73431b3dcd..3689998b5a32 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 fddf3c745e7e..9e01949db6be 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 7ebc65b58dd7..40ee8edd1e0e 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 fbaf85fe0faf..67ea9f046397 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 e9d7b7b9ee0a..d17254904e50 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 8b8e15a51c71..afc9189701f8 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 0a4a7539d348..f410b268971a 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 diff --git a/gcc/testsuite/c-c++-common/strub-parms2.c b/gcc/testsuite/c-c++-common/strub-parms2.c index 147171d96d5a..6f572115a88c 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 diff --git a/gcc/testsuite/c-c++-common/strub-parms3.c b/gcc/testsuite/c-c++-common/strub-parms3.c index 4e92682895a4..7383fea9ce88 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 e2f9d8aebca5..d2b4b52c51e6 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 98474435d2e5..9e5a8e76b6c3 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 1de15342595e..aaeba2a2159a 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 f9209c819004..30cbdd819f17 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 bed1dcfb54a4..911fdfb6db9a 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 6bf0071f52b9..9b23ee3ac331 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 4732f515bf70..4b3a8f843ea1 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 8d6424c479a3..3627a2406000 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 000000000000..7a030cdb9e9e --- /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 368522442066..503eb1734e36 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 b4f288832182..3bf1aa30b4af 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 e48e0610e079..ba4b1623e281 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 87cda7ab21b1..043813b1de46 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 000000000000..3586f4f679df --- /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 000000000000..d6fb4c525c4a --- /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 000000000000..cb5c4049495c --- /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 eb6250fd39c9..67014aa5de84 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 b5e45ab0525a..86dbee6746d1 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 96aa7fe4b07f..9da120f61564 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 5e956cb1a9b6..22056713cce4 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 73d650292dfb..a105c66d7a9c 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 2584f1f974a5..386200c2784a 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 d819f54ec023..817e9fa2118b 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 7c27a2a1a6dc..132ab63ef733 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 e66d903780af..b660702d26e7 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 5e08e0e58c65..fc44eef6f8fb 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 a818e7a38bb5..85e2f59055b5 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 ddb0b5c0543b..0a5edac414df 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 c165f312f16d..988954e7ed6b 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 69fcff8d3763..d3ca91389a70 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 ff006224909b..89b5979cf7b7 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 614b02228ba2..4917dda8826d 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 f9a6b4a16faf..c45903856d4f 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 b4a7f3992bba..b0d6139f0a87 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 ef634d351265..1148c246f205 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 e1f179e160e5..06a72d86d2c5 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 70b558afad04..83ea1af7056e 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 a262a086837b..2643136f178c 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 4c4bd50c209a..8bda129b77dc 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 ce195c6b1f1b..00bcbdd097af 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 75cd54ccb5b5..ea7c40e7912b 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 7458b3fb54da..fdf100428631 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 5d60a7775f4b..1228a6659972 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 c2ad710858e8..e5047a988f5b 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 3b36b8e5d68e..0e84a4bab80f 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 57f9baf758de..edc98486dc93 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 08de3f1c3b17..487ed08bb660 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 459f6886c549..a85447ffabfa 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 0d367fb83d09..beb8b811f8fc 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 c226ab10ff65..6ae45fadd70b 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 a7911f1fa721..8f4849c7fde7 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 6ebebcd01e8e..14f28e3c276b 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 29e6996ecf61..488a2d64afe3 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 dae470601643..4a8653c4d843 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 10445d7cf845..eb7826dc990f 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 3dbcc4a357cb..f23d4675def3 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 09756a74b7d8..9c4c7f696371 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 da56acaa957d..613db69305e0 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 825e395e6819..245b0a830f69 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 e918b3926311..b9bfe50e9296 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 8f0212a75866..f43854705d07 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 bf77321cef79..7a38a4c49ba8 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 e8880dbc4373..7992b7344fb8 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 217367e712d8..abfb120b5146 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 a11adbfb5a9d..68d3230b5356 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 c488c20826fd..3cb81ea03f76 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 3d158de28031..7c6affa06d4a 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 6a504e09198b..64b7e65fe9b0 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 3fcce6be49d6..40a60c198cfe 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 d8163c5af990..3f77283490ef 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 cf149209652e..567158955a32 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 2fc9d5d7c93e..9c0e415501a8 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