public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aoliva/heads/strub)] strub type checking
@ 2021-08-04 9:04 Alexandre Oliva
0 siblings, 0 replies; 3+ messages in thread
From: Alexandre Oliva @ 2021-08-04 9:04 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:396d2d0536e89b78ace8ce2f806031e8dfcdcb35
commit 396d2d0536e89b78ace8ce2f806031e8dfcdcb35
Author: Alexandre Oliva <oliva@gnu.org>
Date: Wed Aug 4 05:52:43 2021 -0300
strub type checking
Diff:
---
gcc/ipa-strub.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/gcc/ipa-strub.c b/gcc/ipa-strub.c
index e302f0ec1c5..81d961ac44e 100644
--- a/gcc/ipa-strub.c
+++ b/gcc/ipa-strub.c
@@ -429,12 +429,12 @@ can_strub_internally_p (cgraph_node *node, bool report = false)
node->decl);
}
- if (result)
- /* Since we're not changing the function identity proper, just
- moving its full implementation, we *could* disable
- fun->cannot_be_copied_reason and/or temporarily drop a noclone
- attribute. */
- gcc_checking_assert (tree_versionable_function_p (node->decl));
+ /* Since we're not changing the function identity proper, just
+ moving its full implementation, we *could* disable
+ fun->cannot_be_copied_reason and/or temporarily drop a noclone
+ attribute. */
+ gcc_checking_assert (!result || !node->has_gimple_body_p ()
+ || tree_versionable_function_p (node->decl));
return result;
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* [gcc(refs/users/aoliva/heads/strub)] strub type checking
@ 2021-08-04 12:46 Alexandre Oliva
0 siblings, 0 replies; 3+ messages in thread
From: Alexandre Oliva @ 2021-08-04 12:46 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:0f88209aa4540dba4b31b7926f0b098685ac8aae
commit 0f88209aa4540dba4b31b7926f0b098685ac8aae
Author: Alexandre Oliva <oliva@adacore.com>
Date: Wed Aug 4 09:45:32 2021 -0300
strub type checking
Diff:
---
gcc/ipa-strub.c | 65 ++---
gcc/testsuite/c-c++-common/strub-O2.c | 2 +-
gcc/testsuite/c-c++-common/strub-O2fni.c | 6 +-
gcc/testsuite/c-c++-common/strub-O3fni.c | 4 +-
gcc/testsuite/c-c++-common/strub-Og.c | 2 +-
gcc/testsuite/c-c++-common/strub-Os.c | 2 +-
gcc/testsuite/c-c++-common/strub-all1.c | 4 +-
gcc/testsuite/c-c++-common/strub-at-calls1.c | 4 +-
gcc/testsuite/c-c++-common/strub-default1.c | 4 +-
gcc/testsuite/c-c++-common/strub-internal1.c | 4 +-
.../c-c++-common/torture/strub-callable1.c | 13 +
.../c-c++-common/torture/strub-callable2.c | 264 +++++++++++++++++++++
gcc/testsuite/c-c++-common/torture/strub-const1.c | 18 ++
gcc/testsuite/c-c++-common/torture/strub-const2.c | 22 ++
gcc/testsuite/c-c++-common/torture/strub-const3.c | 13 +
gcc/testsuite/c-c++-common/torture/strub-const4.c | 17 ++
gcc/testsuite/c-c++-common/torture/strub-data5.c | 4 +-
gcc/testsuite/c-c++-common/torture/strub-pure1.c | 18 ++
gcc/testsuite/c-c++-common/torture/strub-pure2.c | 22 ++
gcc/testsuite/c-c++-common/torture/strub-pure3.c | 13 +
gcc/testsuite/c-c++-common/torture/strub-pure4.c | 17 ++
21 files changed, 473 insertions(+), 45 deletions(-)
diff --git a/gcc/ipa-strub.c b/gcc/ipa-strub.c
index e302f0ec1c5..41ff473411a 100644
--- a/gcc/ipa-strub.c
+++ b/gcc/ipa-strub.c
@@ -263,7 +263,7 @@ calls_builtin_apply_args_p (cgraph_node *node, bool report = false)
break;
sorry_at (gimple_location (e->call_stmt),
- "at-calls strub does not support call to %qD",
+ "at-calls %<strub%> does not support call to %qD",
cdecl);
}
@@ -292,7 +292,8 @@ can_strub_p (cgraph_node *node, bool report = false)
return result;
sorry_at (DECL_SOURCE_LOCATION (node->decl),
- "%qD is not eligible for strub because of attribute %<noipa%>",
+ "%qD is not eligible for %<strub%>"
+ " because of attribute %<noipa%>",
node->decl);
}
@@ -352,7 +353,7 @@ can_strub_internally_p (cgraph_node *node, bool report = false)
return result;
sorry_at (DECL_SOURCE_LOCATION (node->decl),
- "%qD is not eligible for internal strub"
+ "%qD is not eligible for internal %<strub%>"
" because of attribute %<noclone%>",
node->decl);
}
@@ -372,7 +373,7 @@ can_strub_internally_p (cgraph_node *node, bool report = false)
return result;
sorry_at (gimple_location (e->call_stmt),
- "internal strub does not support call to %qD",
+ "internal %<strub%> does not support call to %qD",
cdecl);
}
@@ -411,7 +412,7 @@ can_strub_internally_p (cgraph_node *node, bool report = false)
return result;
sorry_at (gimple_location (label_stmt),
- "internal strub does not support user labels");
+ "internal %<strub%> does not support user labels");
}
}
@@ -425,16 +426,16 @@ can_strub_internally_p (cgraph_node *node, bool report = false)
return result;
sorry_at (DECL_SOURCE_LOCATION (node->decl),
- "%qD has too many arguments for internal strub",
+ "%qD has too many arguments for internal %<strub%>",
node->decl);
}
- if (result)
- /* Since we're not changing the function identity proper, just
- moving its full implementation, we *could* disable
- fun->cannot_be_copied_reason and/or temporarily drop a noclone
- attribute. */
- gcc_checking_assert (tree_versionable_function_p (node->decl));
+ /* Since we're not changing the function identity proper, just
+ moving its full implementation, we *could* disable
+ fun->cannot_be_copied_reason and/or temporarily drop a noclone
+ attribute. */
+ gcc_checking_assert (!result || !node->has_gimple_body_p ()
+ || tree_versionable_function_p (node->decl));
return result;
}
@@ -698,7 +699,8 @@ compute_strub_mode (cgraph_node *node, tree strub_attr)
{
gcc_checking_assert (analyze_body);
error_at (DECL_SOURCE_LOCATION (node->decl),
- "%qD requires strub, but no viable strub mode was found",
+ "%qD requires %<strub%>,"
+ " but no viable %<strub%> mode was found",
node->decl);
break;
}
@@ -751,7 +753,7 @@ set_strub_mode_to (cgraph_node *node, enum strub_mode mode)
&& mode == STRUB_INLINABLE))
{
error_at (DECL_SOURCE_LOCATION (node->decl),
- "strub mode %i selected for %qD, when %i was requested",
+ "%<strub%> mode %i selected for %qD, when %i was requested",
(int) mode, node->decl,
(int) get_strub_mode_from_attr (attr));
if (node->alias)
@@ -979,7 +981,7 @@ verify_strub ()
if (callee_mode == STRUB_DISABLED
|| callee_mode == STRUB_INTERNAL)
error_at (gimple_location (e->call_stmt),
- "indirect non-strub call in strub context %qD",
+ "indirect non-%<strub%> call in %<strub%> context %qD",
node->decl);
}
@@ -987,9 +989,17 @@ verify_strub ()
{
gcc_checking_assert (!e->indirect_unknown_callee);
if (!strub_callable_from_p (e->callee, node))
- error_at (gimple_location (e->call_stmt),
- "calling non-strub %qD in strub context %qD",
- e->callee->decl, node->decl);
+ {
+ if (get_strub_mode (e->callee) != STRUB_INLINABLE)
+ error_at (gimple_location (e->call_stmt),
+ "calling non-%<strub%> %qD in %<strub%> context %qD",
+ e->callee->decl, node->decl);
+ else
+ error_at (gimple_location (e->call_stmt),
+ "calling %<always_inline%> %<strub%> %qD"
+ " in non-%<strub%> context %qD",
+ e->callee->decl, node->decl);
+ }
}
}
@@ -1067,7 +1077,7 @@ public:
/* Use a distinct ptr_type_node to denote the watermark, so that we can
recognize it in arg lists and avoid modifying types twice. */
- DEF_TYPE (wmt, build_distinct_type_copy (ptr_type_node))
+ DEF_TYPE (wmt, build_variant_type_copy (ptr_type_node))
DEF_TYPE (pwmt, build_pointer_type (get_wmt ()))
@@ -1507,7 +1517,7 @@ pass_ipa_strub::adjust_at_calls_type (tree type)
tree qpwmptrt = get_qpwmt ();
while (*tlist && TREE_VALUE (*tlist) != void_type_node)
{
- /* The type has alreayd been adjusted. */
+ /* The type has already been adjusted. */
if (TREE_VALUE (*tlist) == qpwmptrt)
return named_args;
named_args++;
@@ -1909,7 +1919,7 @@ pass_ipa_strub::execute (function *)
if (!DECL_STRUCT_FUNCTION (onode->decl))
{
inform (DECL_SOURCE_LOCATION (onode->decl),
- "not splitting struct-less function %qD for stack scrubbing",
+ "not splitting struct-less function %qD for %<strub%>",
onode->decl);
continue;
}
@@ -1917,7 +1927,7 @@ pass_ipa_strub::execute (function *)
if (!onode->lowered)
{
inform (DECL_SOURCE_LOCATION (onode->decl),
- "not splitting non-lowered function %qD for stack scrubbing",
+ "not splitting non-lowered function %qD for %<strub%>",
onode->decl);
continue;
}
@@ -1929,7 +1939,7 @@ pass_ipa_strub::execute (function *)
if (!tree_versionable_function_p (onode->decl))
{
inform (DECL_SOURCE_LOCATION (onode->decl),
- "%qD cannot be split for stack scrubbing",
+ "%qD cannot be split for %<strub%>",
onode->decl);
continue;
}
@@ -1982,7 +1992,7 @@ pass_ipa_strub::execute (function *)
if (!nnode)
{
error_at (DECL_SOURCE_LOCATION (onode->decl),
- "failed to split %qD for stack scrubbing",
+ "failed to split %qD for %<strub%>",
onode->decl);
continue;
}
@@ -2582,9 +2592,10 @@ pass_ipa_strub::execute (function *)
else if (fndecl && is_stdarg
&& fndecl_built_in_p (fndecl, BUILT_IN_VA_START))
{
- if (builtin_decl_explicit (BUILT_IN_VA_START) != fndecl)
- sorry_at (gimple_location (call),
- "nonstandard stdarg conventions");
+ /* Using a non-default stdarg ABI makes the function ineligible
+ for internal strub. */
+ gcc_checking_assert (builtin_decl_explicit (BUILT_IN_VA_START)
+ == fndecl);
tree bvacopy = builtin_decl_explicit (BUILT_IN_VA_COPY);
gimple_call_set_fndecl (call, bvacopy);
tree arg = vaptr;
diff --git a/gcc/testsuite/c-c++-common/strub-O2.c b/gcc/testsuite/c-c++-common/strub-O2.c
index 9cc39e763b1..7848c46d179 100644
--- a/gcc/testsuite/c-c++-common/strub-O2.c
+++ b/gcc/testsuite/c-c++-common/strub-O2.c
@@ -13,4 +13,4 @@ int f() {
/* { dg-final { scan-rtl-dump-not "strub_enter" "expand" } } */
/* { dg-final { scan-rtl-dump-not "strub_update" "expand" } } */
/* { dg-final { scan-rtl-dump "strub_leave" "expand" } } */
-/* { dg-final { scan-rtl-dump "\n\[(\]call_insn\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
+/* { dg-final { scan-rtl-dump "\[(\]call\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
diff --git a/gcc/testsuite/c-c++-common/strub-O2fni.c b/gcc/testsuite/c-c++-common/strub-O2fni.c
index 51cae845d5f..85a8f76785e 100644
--- a/gcc/testsuite/c-c++-common/strub-O2fni.c
+++ b/gcc/testsuite/c-c++-common/strub-O2fni.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fstrub=default -fdump-rtl-expand -fno-inline-functions" } */
+/* { dg-options "-O2 -fstrub=default -fdump-rtl-expand -fno-inline" } */
-/* With -fno-inline-functions, none of the strub builtins are inlined. */
+/* With -fno-inline, none of the strub builtins are inlined. */
int __attribute__ ((__strub__)) var;
@@ -12,4 +12,4 @@ int f() {
/* { dg-final { scan-rtl-dump "strub_enter" "expand" } } */
/* { dg-final { scan-rtl-dump "strub_update" "expand" } } */
/* { dg-final { scan-rtl-dump "strub_leave" "expand" } } */
-/* { dg-final { scan-rtl-dump-not "\n\[(\]call_insn\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
+/* { dg-final { scan-rtl-dump-not "\[(\]call\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
diff --git a/gcc/testsuite/c-c++-common/strub-O3fni.c b/gcc/testsuite/c-c++-common/strub-O3fni.c
index 8f67b613be8..a2eedfd96b2 100644
--- a/gcc/testsuite/c-c++-common/strub-O3fni.c
+++ b/gcc/testsuite/c-c++-common/strub-O3fni.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O3 -fstrub=default -fdump-rtl-expand -fno-inline" } */
-/* With -fno-inline-functions, none of the strub builtins are inlined. */
+/* With -fno-inline, none of the strub builtins are inlined. */
int __attribute__ ((__strub__)) var;
@@ -12,4 +12,4 @@ int f() {
/* { dg-final { scan-rtl-dump "strub_enter" "expand" } } */
/* { dg-final { scan-rtl-dump "strub_update" "expand" } } */
/* { dg-final { scan-rtl-dump "strub_leave" "expand" } } */
-/* { dg-final { scan-rtl-dump-not "\n\[(\]call_insn\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
+/* { dg-final { scan-rtl-dump-not "\[(\]call\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
diff --git a/gcc/testsuite/c-c++-common/strub-Og.c b/gcc/testsuite/c-c++-common/strub-Og.c
index 6f60349573f..e5cb1f60541 100644
--- a/gcc/testsuite/c-c++-common/strub-Og.c
+++ b/gcc/testsuite/c-c++-common/strub-Og.c
@@ -13,4 +13,4 @@ int f() {
/* { dg-final { scan-rtl-dump-not "strub_enter" "expand" } } */
/* { dg-final { scan-rtl-dump "strub_update" "expand" } } */
/* { dg-final { scan-rtl-dump "strub_leave" "expand" } } */
-/* { dg-final { scan-rtl-dump-not "\n\[(\]call_insn\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
+/* { dg-final { scan-rtl-dump-not "\[(\]call\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
diff --git a/gcc/testsuite/c-c++-common/strub-Os.c b/gcc/testsuite/c-c++-common/strub-Os.c
index 5d1c08a7528..194aacc2c05 100644
--- a/gcc/testsuite/c-c++-common/strub-Os.c
+++ b/gcc/testsuite/c-c++-common/strub-Os.c
@@ -15,4 +15,4 @@ int f() {
/* { dg-final { scan-rtl-dump-not "strub_enter" "expand" } } */
/* { dg-final { scan-rtl-dump-not "strub_update" "expand" } } */
/* { dg-final { scan-rtl-dump "strub_leave" "expand" } } */
-/* { dg-final { scan-rtl-dump-not "\n\[(\]call_insn\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
+/* { dg-final { scan-rtl-dump-not "\[(\]call\[^\n\]*strub_leave.*\n\[(\]code_label" "expand" } } */
diff --git a/gcc/testsuite/c-c++-common/strub-all1.c b/gcc/testsuite/c-c++-common/strub-all1.c
index 54daf84656c..46e84bf6560 100644
--- a/gcc/testsuite/c-c++-common/strub-all1.c
+++ b/gcc/testsuite/c-c++-common/strub-all1.c
@@ -3,9 +3,9 @@
/* h becomes STRUB_CALLABLE, rather than STRUB_INLINABLE, because of the
strub-enabling -fstrub flag, and gets inlined before pass_ipa_strub. */
-static void
+static inline void
__attribute__ ((__always_inline__))
-h() { /* { dg-warning "might not be inlinable" } */
+h() {
}
/* g becomes STRUB_AT_CALLS, because of the flag. */
diff --git a/gcc/testsuite/c-c++-common/strub-at-calls1.c b/gcc/testsuite/c-c++-common/strub-at-calls1.c
index 0d1b9fce833..d964b07ae5d 100644
--- a/gcc/testsuite/c-c++-common/strub-at-calls1.c
+++ b/gcc/testsuite/c-c++-common/strub-at-calls1.c
@@ -3,9 +3,9 @@
/* h becomes STRUB_CALLABLE, rather than STRUB_INLINABLE, because of the
strub-enabling -fstrub flag, and gets inlined before pass_ipa_strub. */
-static void
+static inline void
__attribute__ ((__always_inline__))
-h() { /* { dg-warning "might not be inlinable" } */
+h() {
}
/* g becomes STRUB_AT_CALLS, because of the flag. */
diff --git a/gcc/testsuite/c-c++-common/strub-default1.c b/gcc/testsuite/c-c++-common/strub-default1.c
index a1e1803aadc..2dfdb948e7b 100644
--- a/gcc/testsuite/c-c++-common/strub-default1.c
+++ b/gcc/testsuite/c-c++-common/strub-default1.c
@@ -6,9 +6,9 @@ static int __attribute__ ((__strub__)) var;
/* h becomes STRUB_STRUB_INLINABLE, because of the use of the strub variable,
and the always_inline flag. It would get inlined before pass_ipa_strub, if
it weren't for the error. */
-static void
+static inline void
__attribute__ ((__always_inline__))
-h() { /* { dg-warning "might not be inlinable" } */
+h() {
var++;
}
diff --git a/gcc/testsuite/c-c++-common/strub-internal1.c b/gcc/testsuite/c-c++-common/strub-internal1.c
index b9bd787df0a..a74658c9ac9 100644
--- a/gcc/testsuite/c-c++-common/strub-internal1.c
+++ b/gcc/testsuite/c-c++-common/strub-internal1.c
@@ -3,9 +3,9 @@
/* h becomes STRUB_CALLABLE, rather than STRUB_INLINABLE, because of the
strub-enabling -fstrub flag, and gets inlined before pass_ipa_strub. */
-static void
+static inline void
__attribute__ ((__always_inline__))
-h() { /* { dg-warning "might not be inlinable" } */
+h() {
}
/* g becomes STRUB_INTERNAL because of the flag, and gets split into
diff --git a/gcc/testsuite/c-c++-common/torture/strub-callable1.c b/gcc/testsuite/c-c++-common/torture/strub-callable1.c
new file mode 100644
index 00000000000..45965f275c9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-callable1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=default -fdump-ipa-strub -fno-inline" } */
+
+/* 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
+ contexts. */
+
+#define OMIT_IMPERMISSIBLE_CALLS 1
+#include "strub-callable2.c"
+
+/* { dg-final { scan-ipa-dump-times "strub_enter" 45 "strub" } } */
+/* { dg-final { scan-ipa-dump-times "strub_update" 4 "strub" } } */
+/* { dg-final { scan-ipa-dump-times "strub_leave" 45 "strub" } } */
diff --git a/gcc/testsuite/c-c++-common/torture/strub-callable2.c b/gcc/testsuite/c-c++-common/torture/strub-callable2.c
new file mode 100644
index 00000000000..38935e3270b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-callable2.c
@@ -0,0 +1,264 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=default" } */
+
+/* Check that impermissible (cross-strub-context) calls are reported. */
+
+extern int __attribute__ ((__strub__ (3))) xcallable (void);
+extern int __attribute__ ((__strub__ (2))) xinternal (void);
+extern int __attribute__ ((__strub__ (1))) xat_calls (void);
+extern int __attribute__ ((__strub__ (0))) xdisabled (void);
+
+int __attribute__ ((__strub__ (3))) callable (void);
+int __attribute__ ((__strub__ (2))) internal (void);
+int __attribute__ ((__strub__ (1))) at_calls (void);
+int __attribute__ ((__strub__ (0))) disabled (void);
+
+int __attribute__ ((__strub__)) var;
+int var_user (void);
+
+static inline int __attribute__ ((__always_inline__, __strub__ (3)))
+icallable (void);
+static inline int __attribute__ ((__always_inline__, __strub__ (2)))
+iinternal (void);
+static inline int __attribute__ ((__always_inline__, __strub__ (1)))
+iat_calls (void);
+static inline int __attribute__ ((__always_inline__, __strub__ (0)))
+idisabled (void);
+static inline int __attribute__ ((__always_inline__))
+ivar_user (void);
+
+static inline int __attribute__ ((__always_inline__, __strub__ (3)))
+i_callable (void) { return 0; }
+static inline int __attribute__ ((__always_inline__, __strub__ (2)))
+i_internal (void) { return var; }
+static inline int __attribute__ ((__always_inline__, __strub__ (1)))
+i_at_calls (void) { return var; }
+static inline int __attribute__ ((__always_inline__, __strub__ (0)))
+i_disabled (void) { return 0; }
+static inline int __attribute__ ((__always_inline__))
+i_var_user (void) { return var; }
+
+#define CALLS_GOOD_FOR_STRUB_CONTEXT(ISEP) \
+ do { \
+ ret += i ## ISEP ## at_calls (); \
+ ret += i ## ISEP ## internal (); \
+ ret += i ## ISEP ## var_user (); \
+ } while (0)
+
+#define CALLS_GOOD_FOR_NONSTRUB_CONTEXT(ISEP) \
+ do { \
+ ret += internal (); \
+ ret += disabled (); \
+ ret += var_user (); \
+ \
+ ret += i ## ISEP ## disabled (); \
+ \
+ ret += xinternal (); \
+ ret += xdisabled (); \
+ } while (0)
+
+#define CALLS_GOOD_FOR_EITHER_CONTEXT(ISEP) \
+ do { \
+ ret += i ## ISEP ## callable (); \
+ \
+ ret += callable (); \
+ ret += at_calls (); \
+ \
+ ret += xat_calls (); \
+ ret += xcallable (); \
+ } while (0)
+
+/* Not a strub context, so it can call anything.
+ Explicitly declared as callable even from within strub contexts. */
+int __attribute__ ((__strub__ (3)))
+callable (void) {
+ int ret = 0;
+
+ /* CALLS_GOOD_FOR_STRUB_CONTEXT(); */
+#if !OMIT_IMPERMISSIBLE_CALLS
+ ret += iat_calls (); /* { dg-error "in non-.strub. context" } */
+ ret += iinternal (); /* { dg-error "in non-.strub. context" } */
+ ret += ivar_user (); /* { dg-error "in non-.strub. context" } */
+#endif
+ CALLS_GOOD_FOR_EITHER_CONTEXT();
+ CALLS_GOOD_FOR_NONSTRUB_CONTEXT();
+
+ return ret;
+}
+
+/* Internal strubbing means the body is a strub context, so it can only call
+ strub functions, and it's not itself callable from strub functions. */
+int __attribute__ ((__strub__ (2)))
+internal (void) {
+ int ret = var;
+
+ CALLS_GOOD_FOR_STRUB_CONTEXT();
+ CALLS_GOOD_FOR_EITHER_CONTEXT();
+ /* CALLS_GOOD_FOR_NONSTRUB_CONTEXT(); */
+#if !OMIT_IMPERMISSIBLE_CALLS
+ ret += internal (); /* { dg-error "in .strub. context" } */
+ ret += disabled (); /* { dg-error "in .strub. context" } */
+ ret += var_user (); /* { dg-error "in .strub. context" } */
+
+ ret += idisabled (); /* { dg-error "in .strub. context" } */
+
+ ret += xinternal (); /* { dg-error "in .strub. context" } */
+ ret += xdisabled (); /* { dg-error "in .strub. context" } */
+#endif
+
+ return ret;
+}
+
+int __attribute__ ((__strub__ (1)))
+at_calls (void) {
+ int ret = var;
+
+ CALLS_GOOD_FOR_STRUB_CONTEXT();
+ CALLS_GOOD_FOR_EITHER_CONTEXT();
+ /* CALLS_GOOD_FOR_NONSTRUB_CONTEXT(); */
+#if !OMIT_IMPERMISSIBLE_CALLS
+ ret += internal (); /* { dg-error "in .strub. context" } */
+ ret += disabled (); /* { dg-error "in .strub. context" } */
+ ret += var_user (); /* { dg-error "in .strub. context" } */
+
+ ret += idisabled (); /* { dg-error "in .strub. context" } */
+
+ ret += xinternal (); /* { dg-error "in .strub. context" } */
+ ret += xdisabled (); /* { dg-error "in .strub. context" } */
+#endif
+
+ return ret;
+}
+
+int __attribute__ ((__strub__ (0)))
+disabled () {
+ int ret = 0;
+
+ /* CALLS_GOOD_FOR_STRUB_CONTEXT(); */
+#if !OMIT_IMPERMISSIBLE_CALLS
+ ret += iat_calls (); /* { dg-error "in non-.strub. context" } */
+ ret += iinternal (); /* { dg-error "in non-.strub. context" } */
+ ret += ivar_user (); /* { dg-error "in non-.strub. context" } */
+#endif
+ CALLS_GOOD_FOR_EITHER_CONTEXT();
+ CALLS_GOOD_FOR_NONSTRUB_CONTEXT();
+
+ return ret;
+}
+
+int
+var_user (void) {
+ int ret = var;
+
+ CALLS_GOOD_FOR_STRUB_CONTEXT();
+ CALLS_GOOD_FOR_EITHER_CONTEXT();
+ /* CALLS_GOOD_FOR_NONSTRUB_CONTEXT(); */
+#if !OMIT_IMPERMISSIBLE_CALLS
+ ret += internal (); /* { dg-error "in .strub. context" } */
+ ret += disabled (); /* { dg-error "in .strub. context" } */
+ ret += var_user (); /* { dg-error "in .strub. context" } */
+
+ ret += idisabled (); /* { dg-error "in .strub. context" } */
+
+ ret += xinternal (); /* { dg-error "in .strub. context" } */
+ ret += xdisabled (); /* { dg-error "in .strub. context" } */
+#endif
+
+ return ret;
+}
+
+int
+icallable (void)
+{
+ int ret = 0;
+
+ /* CALLS_GOOD_FOR_STRUB_CONTEXT(_); */
+#if !OMIT_IMPERMISSIBLE_CALLS
+ ret += i_at_calls (); /* { dg-error "in non-.strub. context" } */
+ ret += i_internal (); /* { dg-error "in non-.strub. context" } */
+ ret += i_var_user (); /* { dg-error "in non-.strub. context" } */
+#endif
+ CALLS_GOOD_FOR_EITHER_CONTEXT(_);
+ CALLS_GOOD_FOR_NONSTRUB_CONTEXT(_);
+
+ return ret;
+}
+
+int
+iinternal (void) {
+ int ret = var;
+
+ CALLS_GOOD_FOR_STRUB_CONTEXT(_);
+ CALLS_GOOD_FOR_EITHER_CONTEXT(_);
+ /* CALLS_GOOD_FOR_NONSTRUB_CONTEXT(_); */
+#if !OMIT_IMPERMISSIBLE_CALLS
+ ret += internal (); /* { dg-error "in .strub. context" } */
+ ret += disabled (); /* { dg-error "in .strub. context" } */
+ ret += var_user (); /* { dg-error "in .strub. context" } */
+
+ ret += i_disabled (); /* { dg-error "in .strub. context" } */
+
+ ret += xinternal (); /* { dg-error "in .strub. context" } */
+ ret += xdisabled (); /* { dg-error "in .strub. context" } */
+#endif
+
+ return ret;
+}
+
+int
+iat_calls (void) {
+ int ret = var;
+
+ CALLS_GOOD_FOR_STRUB_CONTEXT(_);
+ CALLS_GOOD_FOR_EITHER_CONTEXT(_);
+ /* CALLS_GOOD_FOR_NONSTRUB_CONTEXT(_); */
+#if !OMIT_IMPERMISSIBLE_CALLS
+ ret += internal (); /* { dg-error "in .strub. context" } */
+ ret += disabled (); /* { dg-error "in .strub. context" } */
+ ret += var_user (); /* { dg-error "in .strub. context" } */
+
+ ret += i_disabled (); /* { dg-error "in .strub. context" } */
+
+ ret += xinternal (); /* { dg-error "in .strub. context" } */
+ ret += xdisabled (); /* { dg-error "in .strub. context" } */
+#endif
+
+ return ret;
+}
+
+int
+idisabled () {
+ int ret = 0;
+
+ /* CALLS_GOOD_FOR_STRUB_CONTEXT(_); */
+#if !OMIT_IMPERMISSIBLE_CALLS
+ ret += i_at_calls (); /* { dg-error "in non-.strub. context" } */
+ ret += i_internal (); /* { dg-error "in non-.strub. context" } */
+ ret += i_var_user (); /* { dg-error "in non-.strub. context" } */
+#endif
+ CALLS_GOOD_FOR_EITHER_CONTEXT(_);
+ CALLS_GOOD_FOR_NONSTRUB_CONTEXT(_);
+
+ return ret;
+}
+
+int
+ivar_user (void) {
+ int ret = var;
+
+ CALLS_GOOD_FOR_STRUB_CONTEXT(_);
+ CALLS_GOOD_FOR_EITHER_CONTEXT(_);
+ /* CALLS_GOOD_FOR_NONSTRUB_CONTEXT(_); */
+#if !OMIT_IMPERMISSIBLE_CALLS
+ ret += internal (); /* { dg-error "in .strub. context" } */
+ ret += disabled (); /* { dg-error "in .strub. context" } */
+ ret += var_user (); /* { dg-error "in .strub. context" } */
+
+ ret += i_disabled (); /* { dg-error "in .strub. context" } */
+
+ ret += xinternal (); /* { dg-error "in .strub. context" } */
+ ret += xdisabled (); /* { dg-error "in .strub. context" } */
+#endif
+
+ return ret;
+}
diff --git a/gcc/testsuite/c-c++-common/torture/strub-const1.c b/gcc/testsuite/c-c++-common/torture/strub-const1.c
new file mode 100644
index 00000000000..100fb0c59a9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-const1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=default -fdump-ipa-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 the call,
+ and another to make sure it is not assumed to be unchanged. */
+
+int __attribute__ ((__strub__, __const__))
+f() {
+ return 0;
+}
+
+int
+g() {
+ return f();
+}
+
+/* { dg-final { scan-ipa-dump-times "__asm__" 2 "strub" } } */
diff --git a/gcc/testsuite/c-c++-common/torture/strub-const2.c b/gcc/testsuite/c-c++-common/torture/strub-const2.c
new file mode 100644
index 00000000000..9e818ac9748
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-const2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=default -fdump-ipa-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
+ before the call, and another to make sure it is not assumed to be
+ unchanged. */
+
+int __attribute__ ((__strub__))
+#if ! __OPTIMIZE__
+__attribute__ ((__const__))
+#endif
+f() {
+ return 0;
+}
+
+int
+g() {
+ return f();
+}
+
+/* { dg-final { scan-ipa-dump-times "__asm__" 2 "strub" } } */
diff --git a/gcc/testsuite/c-c++-common/torture/strub-const3.c b/gcc/testsuite/c-c++-common/torture/strub-const3.c
new file mode 100644
index 00000000000..d40e8aa45cb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-const3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=default -fdump-ipa-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,
+ and another to make sure it is not assumed to be unchanged. */
+
+int __attribute__ ((__strub__ (2), __const__))
+f() {
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump-times "__asm__" 2 "strub" } } */
diff --git a/gcc/testsuite/c-c++-common/torture/strub-const4.c b/gcc/testsuite/c-c++-common/torture/strub-const4.c
new file mode 100644
index 00000000000..d4cbdaf10f3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-const4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=default -fdump-ipa-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
+ before the call, and another to make sure it is not assumed to be
+ unchanged. */
+
+int __attribute__ ((__strub__ (2)))
+#if ! __OPTIMIZE__
+__attribute__ ((__const__))
+#endif
+f() {
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump-times "__asm__" 2 "strub" } } */
diff --git a/gcc/testsuite/c-c++-common/torture/strub-data5.c b/gcc/testsuite/c-c++-common/torture/strub-data5.c
index 251790d4bbb..e0ee6cbddda 100644
--- a/gcc/testsuite/c-c++-common/torture/strub-data5.c
+++ b/gcc/testsuite/c-c++-common/torture/strub-data5.c
@@ -7,9 +7,9 @@ typedef int __attribute__ ((__strub__)) strub_int;
strub_int *ptr;
int *f () {
- return ptr; /* { dg-warn "incompatible" } */
+ return ptr; /* { dg-warning "incompatible" } */
}
strub_int *g () {
- return f (); /* { dg-warn "incompatible" } */
+ return f (); /* { dg-warning "incompatible" } */
}
diff --git a/gcc/testsuite/c-c++-common/torture/strub-pure1.c b/gcc/testsuite/c-c++-common/torture/strub-pure1.c
new file mode 100644
index 00000000000..cb223da6efc
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-pure1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=default -fdump-ipa-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. */
+
+int __attribute__ ((__strub__, __pure__))
+f() {
+ static int i; /* Stop it from being detected as const. */
+ return i;
+}
+
+int
+g() {
+ return f();
+}
+
+/* { dg-final { scan-ipa-dump-times "__asm__" 1 "strub" } } */
diff --git a/gcc/testsuite/c-c++-common/torture/strub-pure2.c b/gcc/testsuite/c-c++-common/torture/strub-pure2.c
new file mode 100644
index 00000000000..67d1434b1f8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-pure2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=default -fdump-ipa-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
+ unchanged. */
+
+int __attribute__ ((__strub__))
+#if ! __OPTIMIZE__ /* At -O0, implicit pure detection doesn't run. */
+__attribute__ ((__pure__))
+#endif
+f() {
+ static int i; /* Stop it from being detected as const. */
+ return i;
+}
+
+int
+g() {
+ return f();
+}
+
+/* { dg-final { scan-ipa-dump-times "__asm__" 1 "strub" } } */
diff --git a/gcc/testsuite/c-c++-common/torture/strub-pure3.c b/gcc/testsuite/c-c++-common/torture/strub-pure3.c
new file mode 100644
index 00000000000..59f02ea901f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-pure3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=default -fdump-ipa-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. */
+
+int __attribute__ ((__strub__ (2), __pure__))
+f() {
+ static int i; /* Stop it from being detected as const. */
+ return i;
+}
+
+/* { dg-final { scan-ipa-dump-times "__asm__" 1 "strub" } } */
diff --git a/gcc/testsuite/c-c++-common/torture/strub-pure4.c b/gcc/testsuite/c-c++-common/torture/strub-pure4.c
new file mode 100644
index 00000000000..973e909217d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/strub-pure4.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fstrub=default -fdump-ipa-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
+ unchanged. */
+
+int __attribute__ ((__strub__ (2)))
+#if ! __OPTIMIZE__ /* At -O0, implicit pure detection doesn't run. */
+__attribute__ ((__pure__))
+#endif
+f() {
+ static int i; /* Stop it from being detected as const. */
+ return i;
+}
+
+/* { dg-final { scan-ipa-dump-times "__asm__" 1 "strub" } } */
^ permalink raw reply [flat|nested] 3+ messages in thread
* [gcc(refs/users/aoliva/heads/strub)] strub type checking
@ 2021-08-04 8:55 Alexandre Oliva
0 siblings, 0 replies; 3+ messages in thread
From: Alexandre Oliva @ 2021-08-04 8:55 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:208e30374d1133458a6a12546a8daa791c75016a
commit 208e30374d1133458a6a12546a8daa791c75016a
Author: Alexandre Oliva <oliva@gnu.org>
Date: Wed Aug 4 05:52:43 2021 -0300
strub type checking
Diff:
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-08-04 12:46 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-04 9:04 [gcc(refs/users/aoliva/heads/strub)] strub type checking Alexandre Oliva
-- strict thread matches above, loose matches on Subject: below --
2021-08-04 12:46 Alexandre Oliva
2021-08-04 8:55 Alexandre Oliva
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).