aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/c-c++-common
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite/c-c++-common')
-rw-r--r--gcc/testsuite/c-c++-common/attr-fallthrough-2.c4
-rw-r--r--gcc/testsuite/c-c++-common/musttail15.c14
-rw-r--r--gcc/testsuite/c-c++-common/musttail16.c33
-rw-r--r--gcc/testsuite/c-c++-common/musttail17.c17
-rw-r--r--gcc/testsuite/c-c++-common/musttail18.c14
-rw-r--r--gcc/testsuite/c-c++-common/musttail19.c17
-rw-r--r--gcc/testsuite/c-c++-common/musttail20.c15
-rw-r--r--gcc/testsuite/c-c++-common/musttail21.c5
-rw-r--r--gcc/testsuite/c-c++-common/musttail22.c90
-rw-r--r--gcc/testsuite/c-c++-common/musttail23.c45
-rw-r--r--gcc/testsuite/c-c++-common/musttail24.c21
11 files changed, 273 insertions, 2 deletions
diff --git a/gcc/testsuite/c-c++-common/attr-fallthrough-2.c b/gcc/testsuite/c-c++-common/attr-fallthrough-2.c
index 156b413..434eab7 100644
--- a/gcc/testsuite/c-c++-common/attr-fallthrough-2.c
+++ b/gcc/testsuite/c-c++-common/attr-fallthrough-2.c
@@ -21,8 +21,8 @@ fn (int i)
case 3:
bar (1);
__attribute__((fallthrough)) /* { dg-warning "not followed" "" { target c } } */
- case 4: /* { dg-error "expected" } */
- bar (1);
+ case 4: /* { dg-error "expected" "" { target c } } */
+ bar (1); /* { dg-warning "'fallthrough' attribute ignored" "" { target c++ } .-1 } */
__attribute__((fallthrough)) 1;
/* { dg-error "expected" "" { target c } .-1 } */
/* { dg-warning "not followed" "" { target *-*-* } .-2 } */
diff --git a/gcc/testsuite/c-c++-common/musttail15.c b/gcc/testsuite/c-c++-common/musttail15.c
new file mode 100644
index 0000000..2addc97
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail15.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { musttail && { c || c++11 } } } } */
+/* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */
+
+int __attribute__((noinline,noclone,noipa))
+callee (int i)
+{
+ return i * i;
+}
+
+int __attribute__((noinline,noclone,noipa))
+caller (int i)
+{
+ __attribute__((musttail)) return callee (i + 1);
+}
diff --git a/gcc/testsuite/c-c++-common/musttail16.c b/gcc/testsuite/c-c++-common/musttail16.c
new file mode 100644
index 0000000..b1e2ff3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail16.c
@@ -0,0 +1,33 @@
+/* { dg-do compile { target { musttail && { c || c++11 } } } } */
+
+struct box { char field[256]; int i; };
+
+int __attribute__((noinline,noclone,noipa))
+test_2_callee (int i, struct box b)
+{
+ if (b.field[0])
+ return 5;
+ return i * i;
+}
+
+int __attribute__((noinline,noclone,noipa))
+test_2_caller (int i)
+{
+ struct box b;
+ __attribute__((musttail)) return test_2_callee (i + 1, b); /* { dg-error "cannot tail-call: " } */
+}
+
+extern void setjmp (void);
+void
+test_3 (void)
+{
+ __attribute__((musttail)) return setjmp (); /* { dg-error "cannot tail-call: " } */
+}
+
+extern float f7(void);
+
+int
+test_6 (void)
+{
+ __attribute__((musttail)) return f7(); /* { dg-error "cannot tail-call: " } */
+}
diff --git a/gcc/testsuite/c-c++-common/musttail17.c b/gcc/testsuite/c-c++-common/musttail17.c
new file mode 100644
index 0000000..490f3c3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail17.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { musttail && { c || c++11 } } } } */
+
+struct box { char field[64]; int i; };
+
+struct box __attribute__((noinline,noclone,noipa))
+returns_struct (int i)
+{
+ struct box b;
+ b.i = i * i;
+ return b;
+}
+
+int __attribute__((noinline,noclone))
+test_1 (int i)
+{
+ __attribute__((musttail)) return returns_struct (i * 5).i; /* { dg-error "cannot tail-call: " } */
+}
diff --git a/gcc/testsuite/c-c++-common/musttail18.c b/gcc/testsuite/c-c++-common/musttail18.c
new file mode 100644
index 0000000..4f34a8d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail18.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { musttail && { c || c++11 } } } } */
+/* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */
+
+void __attribute__((noipa)) f() {}
+
+void f2()
+{
+ __attribute__((__musttail__)) return f2();
+}
+
+void f3()
+{
+ __attribute__((__musttail__)) return f();
+}
diff --git a/gcc/testsuite/c-c++-common/musttail19.c b/gcc/testsuite/c-c++-common/musttail19.c
new file mode 100644
index 0000000..70f9eaf
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail19.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { musttail && { c || c++11 } } } } */
+
+float f1(void);
+
+int f2(void)
+{
+ __attribute__((musttail)) return f1 (); /* { dg-error "changed after call" } */
+}
+
+
+int f3(int *);
+
+int f4(void)
+{
+ int x;
+ __attribute__((musttail)) return f3(&x); /* { dg-error "\(refers to locals|other reasons\)" } */
+}
diff --git a/gcc/testsuite/c-c++-common/musttail20.c b/gcc/testsuite/c-c++-common/musttail20.c
new file mode 100644
index 0000000..70f14ff
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail20.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { struct_musttail && { c || c++11 } } } } */
+/* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */
+
+struct str
+{
+ int a, b;
+};
+struct str
+cstruct (int x)
+{
+ if (x < 10)
+ L:
+ __attribute__((musttail)) return cstruct (x + 1); /* { dg-warning "'musttail' attribute ignored" "" { target c } } */
+ return ((struct str){ x, 0 });
+}
diff --git a/gcc/testsuite/c-c++-common/musttail21.c b/gcc/testsuite/c-c++-common/musttail21.c
new file mode 100644
index 0000000..954209d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail21.c
@@ -0,0 +1,5 @@
+/* { dg-do compile { target { c || c++11 } } } */
+void f(void)
+{
+ __attribute__((musttail)) return; /* { dg-error "cannot tail-call.*return value must be a call" } */
+}
diff --git a/gcc/testsuite/c-c++-common/musttail22.c b/gcc/testsuite/c-c++-common/musttail22.c
new file mode 100644
index 0000000..eb81249
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail22.c
@@ -0,0 +1,90 @@
+/* PR tree-optimization/118430 */
+/* { dg-do compile { target musttail } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times " \[^\n\r]* = bar \\\(\[^\n\r]*\\\); \\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \[^\n\r]* = freddy \\\(\[^\n\r]*\\\); \\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not " (?:bar|freddy) \\\(\[^\n\r]*\\\); \\\[tail call\\\]" "optimized" } } */
+
+__attribute__ ((noipa)) void
+foo (int x)
+{
+ (void) x;
+}
+
+__attribute__ ((noinline)) int
+bar (int x)
+{
+ foo (x);
+ return 1;
+}
+
+__attribute__ ((noinline)) int
+baz (int *x)
+{
+ foo (*x);
+ return 2;
+}
+
+__attribute__((noipa)) int
+qux (int x)
+{
+ {
+ int v;
+ foo (x);
+ baz (&v);
+ }
+ __attribute__((musttail))
+ return bar (x);
+}
+
+__attribute__((noipa)) int
+corge (int x)
+{
+ {
+ int v;
+ foo (x);
+ baz (&v);
+ }
+ return bar (x) + 1;
+}
+
+__attribute__ ((noinline)) float
+freddy (int x)
+{
+ foo (x);
+ return 1.75f;
+}
+
+__attribute__((noipa)) float
+garply (int x)
+{
+ {
+ int v;
+ foo (x);
+ baz (&v);
+ }
+ __attribute__((musttail))
+ return freddy (x);
+}
+
+__attribute__((noipa)) float
+quux (int x)
+{
+ {
+ int v;
+ foo (x);
+ baz (&v);
+ }
+ return freddy (x) + 0.25f;
+}
+
+int v;
+
+int
+main ()
+{
+ qux (v);
+ corge (v);
+ garply (v);
+ quux (v);
+}
diff --git a/gcc/testsuite/c-c++-common/musttail23.c b/gcc/testsuite/c-c++-common/musttail23.c
new file mode 100644
index 0000000..d2ba70b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail23.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-W -Wall" } */
+
+void bar (void);
+
+void
+foo (int x)
+{
+ __attribute__((musttail)); /* { dg-warning "empty declaration" "" { target c } } */
+ /* { dg-warning "attributes at the beginning of statement are ignored" "" { target c++ } .-1 } */
+ if (x == 1)
+ __attribute__((musttail (1))) return bar (); /* { dg-error "'musttail' attribute does not take any arguments" } */
+ if (x == 2)
+ __attribute__((musttail (1, "", 3))) return bar (); /* { dg-error "'musttail' attribute does not take any arguments" } */
+ if (x == 3)
+ [[gnu::musttail (1)]] return bar (); /* { dg-error "'musttail' attribute does not take any arguments" } */
+ /* { dg-error "expected" "" { target c } .-1 } */
+ if (x == 4)
+ [[gnu::musttail (1, "", 3)]] return bar (); /* { dg-error "'musttail' attribute does not take any arguments" } */
+ /* { dg-error "expected" "" { target c } .-1 } */
+ if (x == 3)
+ [[clang::musttail (1)]] return bar (); /* { dg-error "'musttail' attribute does not take any arguments" } */
+ /* { dg-error "expected" "" { target c } .-1 } */
+ if (x == 4)
+ [[clang::musttail (1, "", 3)]] return bar (); /* { dg-error "'musttail' attribute does not take any arguments" } */
+ /* { dg-error "expected" "" { target c } .-1 } */
+ if (x == 5)
+ __attribute__((fallthrough, musttail)) return bar (); /* { dg-warning "attribute 'musttail' mixed with other attributes on 'return' statement" "" { target c } } */
+ /* { dg-warning "attributes at the beginning of statement are ignored" "" { target c++ } .-1 } */
+
+ if (x == 6)
+ [[fallthrough]] [[gnu::musttail]] return bar (); /* { dg-warning "'fallthrough' attribute ignored" "" { target c } } */
+ /* { dg-warning "attributes at the beginning of statement are ignored" "" { target c++ } .-1 } */
+ if (x == 7)
+ [[clang::musttail, fallthrough]] return bar (); /* { dg-warning "'fallthrough' attribute ignored" "" { target c } } */
+ /* { dg-warning "attributes at the beginning of statement are ignored" "" { target c++ } .-1 } */
+ if (x == 8)
+ __attribute__((musttail, musttail)) return bar ();
+ if (x == 9)
+ [[gnu::musttail, gnu::musttail]] return bar ();
+ if (x == 10)
+ [[clang::musttail]] [[clang::musttail]] return bar ();
+ if (x == 11)
+ [[clang::musttail]] [[gnu::musttail]] return bar ();
+}
diff --git a/gcc/testsuite/c-c++-common/musttail24.c b/gcc/testsuite/c-c++-common/musttail24.c
new file mode 100644
index 0000000..10c2d3f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/musttail24.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+#if !__has_attribute (musttail)
+#error missing musttail attribute
+#endif
+#ifdef __cplusplus
+#if !__has_cpp_attribute (gnu::musttail)
+#error missing gnu::musttail attribute
+#endif
+#if !__has_cpp_attribute (clang::musttail)
+#error missing clang::musttail attribute
+#endif
+#else
+#if !__has_c_attribute (gnu::musttail)
+#error missing gnu::musttail attribute
+#endif
+#if !__has_c_attribute (clang::musttail)
+#error missing clang::musttail attribute
+#endif
+#endif