diff options
Diffstat (limited to 'gcc/testsuite/c-c++-common')
-rw-r--r-- | gcc/testsuite/c-c++-common/attr-fallthrough-2.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/musttail15.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/musttail16.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/musttail17.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/musttail18.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/musttail19.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/musttail20.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/musttail21.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/musttail22.c | 90 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/musttail23.c | 45 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/musttail24.c | 21 |
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 |