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.
This commit is contained in:
Alexandre Oliva 2023-12-07 12:58:20 -03:00 committed by Alexandre Oliva
parent d36cac1872
commit f908368d2c
103 changed files with 272 additions and 3 deletions

View file

@ -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"

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -60,6 +60,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-strub.h"
#include "symtab-thunks.h"
#include "attr-fnspec.h"
#include "target.h"
/* This file introduces two passes that, together, implement
machine-independent stack scrubbing, strub for short. It arranges
@ -631,17 +632,60 @@ strub_always_inline_p (cgraph_node *node)
return lookup_attribute ("always_inline", DECL_ATTRIBUTES (node->decl));
}
/* Return TRUE iff the target has strub support for T, a function
decl, or a type used in an indirect call, and optionally REPORT the
reasons for ineligibility. If T is a type and error REPORTing is
enabled, the LOCation (of the indirect call) should be provided. */
static inline bool
strub_target_support_p (tree t, bool report = false,
location_t loc = UNKNOWN_LOCATION)
{
bool result = true;
if (!targetm.have_strub_support_for (t))
{
result = false;
if (!report)
return result;
if (DECL_P (t))
sorry_at (DECL_SOURCE_LOCATION (t),
"%qD is not eligible for %<strub%>"
" on the target system", t);
else
sorry_at (loc,
"unsupported %<strub%> call"
" on the target system");
}
return result;
}
/* Return TRUE iff NODE is potentially eligible for any strub-enabled mode, and
optionally REPORT the reasons for ineligibility. */
static inline bool
can_strub_p (cgraph_node *node, bool report = false)
{
bool result = true;
bool result = strub_target_support_p (node->decl, report);
if (!report && strub_always_inline_p (node))
if (!report && (!result || strub_always_inline_p (node)))
return result;
if (flag_split_stack)
{
result = false;
if (!report)
return result;
sorry_at (DECL_SOURCE_LOCATION (node->decl),
"%qD is not eligible for %<strub%>"
" because %<-fsplit-stack%> is enabled",
node->decl);
}
if (lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
{
result = false;
@ -2417,6 +2461,12 @@ pass_ipa_strub::adjust_at_calls_call (cgraph_edge *e, int named_args,
&& (TREE_TYPE (gimple_call_arg (ocall, named_args))
== get_pwmt ())));
tree tsup;
if (!(tsup = gimple_call_fndecl (ocall)))
tsup = TREE_TYPE (TREE_TYPE (gimple_call_fn (ocall)));
if (!strub_target_support_p (tsup, true, gimple_location (ocall)))
return;
/* If we're already within a strub context, pass on the incoming watermark
pointer, and omit the enter and leave calls around the modified call, as an
optimization, or as a means to satisfy a tail-call requirement. */

View file

@ -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\

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O3 -fstrub=strict -fdump-rtl-expand" } */
/* { dg-require-effective-target strub } */
int __attribute__ ((__strub__)) var;

View file

@ -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. */

View file

@ -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. */

View file

@ -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

View file

@ -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. */

View file

@ -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

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=strict" } */
/* { dg-require-effective-target strub } */
void __attribute__ ((__strub__ ("callable")))
apply_function (void *args)

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=strict" } */
/* { dg-require-effective-target strub } */
extern void __attribute__ ((__strub__))
apply_function (void *args);

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=strict" } */
/* { dg-require-effective-target strub } */
void __attribute__ ((__strub__))
apply_function (void *args)

View file

@ -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

View file

@ -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. */

View file

@ -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

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
/* { dg-require-effective-target strub } */
#include <stdarg.h>

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
/* { dg-require-effective-target strub } */
#include <stdarg.h>

View file

@ -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

View file

@ -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,

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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

View file

@ -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

View file

@ -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" } */

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=strict -fdump-ipa-strubm" } */
/* { dg-require-effective-target strub } */
static int __attribute__ ((__strub__)) var;

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=strict -fdump-ipa-strubm" } */
/* { dg-require-effective-target strub } */
static int __attribute__ ((__strub__)) var;

View file

@ -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"

View file

@ -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+. */

View file

@ -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 } } } */
}

View file

@ -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 ();
}

View file

@ -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);

View file

@ -1,4 +1,5 @@
/* { dg-do compile } */
/* { dg-require-effective-target strub } */
int __attribute__ ((strub)) x;
float __attribute__ ((strub)) f;

View file

@ -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

View file

@ -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. */

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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

View file

@ -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;

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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. */

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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)

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=all" } */
/* { dg-require-effective-target strub } */
#include "strub-inlinable1.c"

View file

@ -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);

View file

@ -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.

View file

@ -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. */

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=relaxed" } */
/* { dg-require-effective-target strub } */
/* This is strub-ptrfn2.c without -Wpedantic.

View file

@ -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. */

View file

@ -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

View file

@ -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. */

View file

@ -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

View file

@ -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

View file

@ -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. */

View file

@ -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. */

View file

@ -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

View file

@ -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"

View file

@ -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")))

View file

@ -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"

View file

@ -1,5 +1,6 @@
// { dg-do run }
// { dg-options "-fstrub=internal" }
// { dg-require-effective-target strub }
// Check that we don't get extra copies.

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
// { dg-require-effective-target strub }
extern int __attribute__((__strub__)) initializer ();

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
// { dg-require-effective-target strub }
extern int __attribute__((__strub__)) initializer ();

View file

@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-fstrub=strict -fdump-ipa-strub" } */
// { dg-require-effective-target strub }
extern int __attribute__((__strub__)) initializer ();

View file

@ -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

View file

@ -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.

View file

@ -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;

View file

@ -1,4 +1,5 @@
-- { dg-do compile }
-- { dg-require-effective-target strub }
procedure Strub_Disp is
package Foo is

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -1,4 +1,5 @@
-- { dg-do compile }
-- { dg-require-effective-target strub }
-- Check that strub mode mismatches between overrider and overridden
-- subprograms are reported.

View file

@ -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.

View file

@ -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

View file

@ -1,4 +1,5 @@
-- { dg-do compile }
-- { dg-require-effective-target strub }
procedure Strub_Renm is
procedure P (X : Integer);

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -1,4 +1,5 @@
-- { dg-do compile }
-- { dg-require-effective-target strub }
with Strub_Attr;
procedure Strub_Var1 is

View file

@ -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.

Some files were not shown because too many files have changed in this diff Show more