Skip to content

Instantly share code, notes, and snippets.

@pietro
Created November 16, 2021 21:23
Show Gist options
  • Save pietro/9a582b054b008e9a4ad3e1afe3a4cc22 to your computer and use it in GitHub Desktop.
Save pietro/9a582b054b008e9a4ad3e1afe3a4cc22 to your computer and use it in GitHub Desktop.
diff --git a/gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c b/gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c
index 1495a4823..d01e4645f 100644
--- a/gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c
+++ b/gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c
@@ -1,5 +1,11 @@
/* { dg-options "-fdelayed-branch" { target sparc*-*-* } } */
+#if __has_attribute (musttail)
+# define MUSTTAIL __attribute__((noinline,noclone,musttail))
+#else
+# define MUSTTAIL __attribute__((noinline,noclone))
+#endif
+
extern void abort (void);
int __attribute__((noinline,noclone))
@@ -8,7 +14,7 @@ callee (int i)
return i * i;
}
-int __attribute__((noinline,noclone))
+int MUSTTAIL
caller (int i)
{
return callee (i + 1);
diff --git a/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c
index c6dfecd32..9f61bbf58 100644
--- a/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c
+++ b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c
@@ -1,6 +1,14 @@
/* Allow nested functions. */
/* { dg-options "-Wno-pedantic" } */
+#if __has_attribute (musttail)
+# define NOINLINE_MUSTTAIL __attribute__((noinline,noclone,musttail))
+# define MUSTTAIL __attribute__((musttail))
+#else
+# define NOINLINE_MUSTTAIL __attribute__((noinline,noclone))
+# define MUSTTAIL
+#endif
+
struct box { char field[64]; int i; };
struct box __attribute__((noinline,noclone))
@@ -11,13 +19,13 @@ returns_struct (int i)
return b;
}
-int __attribute__((noinline,noclone))
+int NOINLINE_MUSTTAIL
test_1 (int i)
{
return returns_struct (i * 5).i; /* { dg-error "cannot tail-call: " } */
}
-int __attribute__((noinline,noclone))
+int NOINLINE_MUSTTAIL
test_2_callee (int i, struct box b)
{
if (b.field[0])
@@ -25,7 +33,7 @@ test_2_callee (int i, struct box b)
return i * i;
}
-int __attribute__((noinline,noclone))
+int NOINLINE_MUSTTAIL
test_2_caller (int i)
{
struct box b;
@@ -33,13 +41,14 @@ test_2_caller (int i)
}
extern void setjmp (void);
-void
+
+void MUSTTAIL
test_3 (void)
{
setjmp (); /* { dg-error "cannot tail-call: " } */
}
-void
+void MUSTTAIL
test_4 (void)
{
void nested (void)
@@ -51,7 +60,7 @@ test_4 (void)
typedef void (fn_ptr_t) (void);
volatile fn_ptr_t fn_ptr;
-void
+void MUSTTAIL
test_5 (void)
{
fn_ptr (); /* { dg-error "cannot tail-call: " } */
diff --git a/gcc/testsuite/gcc.dg/plugin/must_tail_call_attribute_plugin.c b/gcc/testsuite/gcc.dg/plugin/must_tail_call_attribute_plugin.c
new file mode 100644
index 000000000..d237aba1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/must_tail_call_attribute_plugin.c
@@ -0,0 +1,86 @@
+#include "gcc-plugin.h"
+#include "plugin-version.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "print-tree.h"
+
+int plugin_is_GPL_compatible;
+
+static struct plugin_info musttail_plugin_info = {
+ .version = "0.0.1",
+ .help = "Provides musttail attribute\n",
+};
+
+static struct attribute_spec musttail_attr = {
+ .name = "musttail",
+ .min_length = 0,
+ .max_length = 0,
+ .decl_required = true,
+ .type_required = false,
+ .function_type_required = false,
+ .affects_type_identity = false,
+ .handler = NULL,
+ .exclude = NULL,
+};
+
+static void
+register_attributes (void *event_data ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ register_attribute (&musttail_attr);
+}
+
+tree
+cb_walk_tree_fn (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ if (TREE_CODE (*tp) != CALL_EXPR)
+ return NULL_TREE;
+
+ tree call_expr = *tp;
+
+ CALL_EXPR_MUST_TAIL_CALL (call_expr) = 1;
+
+ return NULL_TREE;
+}
+
+static void
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment