summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2015-11-13 00:42:21 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2015-11-13 00:42:21 +0000
commit7828b1e604f22e81815a3c2fc357e319f2807bb8 (patch)
tree0a15c5c8a42974829ad072a1e891cf4cb664ec6c /clang/test
parentc9dd057e3ccdbe44dd2aa2fd0303ff9a26c45f15 (diff)
downloadbcm5719-llvm-7828b1e604f22e81815a3c2fc357e319f2807bb8.tar.gz
bcm5719-llvm-7828b1e604f22e81815a3c2fc357e319f2807bb8.zip
Add support for function attribute 'disable_tail_calls'.
The ``disable_tail_calls`` attribute instructs the backend to not perform tail call optimization inside the marked function. For example, int callee(int); int foo(int a) __attribute__((disable_tail_calls)) { return callee(a); // This call is not tail-call optimized. } Note that this attribute is different from 'not_tail_called', which prevents tail-call optimization to the marked function. rdar://problem/8973573 Differential Revision: http://reviews.llvm.org/D12547 llvm-svn: 252986
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CodeGen/attr-disable-tail-calls.c18
-rw-r--r--clang/test/CodeGenCXX/attr-disable-tail-calls.cpp35
-rw-r--r--clang/test/Sema/attr-disable-tail-calls.c13
-rw-r--r--clang/test/SemaCXX/attr-disable-tail-calls.cpp8
4 files changed, 69 insertions, 5 deletions
diff --git a/clang/test/CodeGen/attr-disable-tail-calls.c b/clang/test/CodeGen/attr-disable-tail-calls.c
index 81413492ff3..d47b14fe8ba 100644
--- a/clang/test/CodeGen/attr-disable-tail-calls.c
+++ b/clang/test/CodeGen/attr-disable-tail-calls.c
@@ -1,11 +1,19 @@
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 %s -emit-llvm -mdisable-tail-calls -o - | FileCheck %s -check-prefix=CHECK -check-prefix=DISABLE
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=ENABLE
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 %s -emit-llvm -mdisable-tail-calls -o - | FileCheck %s -check-prefix=DISABLE
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7.0 %s -emit-llvm -o - | FileCheck %s -check-prefix=ENABLE
-// CHECK: define i32 @f1() [[ATTR:#[0-9]+]] {
+// DISABLE: define i32 @f1() [[ATTRTRUE:#[0-9]+]] {
+// DISABLE: define i32 @f2() [[ATTRTRUE]] {
+// ENABLE: define i32 @f1() [[ATTRFALSE:#[0-9]+]] {
+// ENABLE: define i32 @f2() [[ATTRTRUE:#[0-9]+]] {
int f1() {
return 0;
}
-// DISABLE: attributes [[ATTR]] = { {{.*}} "disable-tail-calls"="true" {{.*}} }
-// ENABLE: attributes [[ATTR]] = { {{.*}} "disable-tail-calls"="false" {{.*}} }
+int f2() __attribute__((disable_tail_calls)) {
+ return 0;
+}
+
+// DISABLE: attributes [[ATTRTRUE]] = { {{.*}}"disable-tail-calls"="true"{{.*}} }
+// ENABLE: attributes [[ATTRFALSE]] = { {{.*}}"disable-tail-calls"="false"{{.*}} }
+// ENABLE: attributes [[ATTRTRUE]] = { {{.*}}"disable-tail-calls"="true"{{.*}} }
diff --git a/clang/test/CodeGenCXX/attr-disable-tail-calls.cpp b/clang/test/CodeGenCXX/attr-disable-tail-calls.cpp
new file mode 100644
index 00000000000..b9a3c2712f0
--- /dev/null
+++ b/clang/test/CodeGenCXX/attr-disable-tail-calls.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+class B {
+public:
+ [[clang::disable_tail_calls]] virtual int m1() { return 1; }
+ virtual int m2() { return 2; }
+ int m3() { return 3; }
+ [[clang::disable_tail_calls]] int m4();
+};
+
+class D : public B {
+public:
+ int m1() override { return 11; }
+ [[clang::disable_tail_calls]] int m2() override { return 22; }
+};
+
+int foo1() {
+ B *b = new B;
+ D *d = new D;
+ int t = 0;
+ t += b->m1() + b->m2() + b->m3() + b->m4();
+ t += d->m1() + d->m2();
+ return t;
+}
+
+// CHECK: define linkonce_odr i32 @_ZN1B2m3Ev(%class.B* %this) [[ATTRFALSE:#[0-9]+]]
+// CHECK: declare i32 @_ZN1B2m4Ev(%class.B*) [[ATTRTRUE0:#[0-9]+]]
+// CHECK: define linkonce_odr i32 @_ZN1B2m1Ev(%class.B* %this) unnamed_addr [[ATTRTRUE1:#[0-9]+]]
+// CHECK: define linkonce_odr i32 @_ZN1B2m2Ev(%class.B* %this) unnamed_addr [[ATTRFALSE:#[0-9]+]]
+// CHECK: define linkonce_odr i32 @_ZN1D2m1Ev(%class.D* %this) unnamed_addr [[ATTRFALSE:#[0-9]+]]
+// CHECK: define linkonce_odr i32 @_ZN1D2m2Ev(%class.D* %this) unnamed_addr [[ATTRTRUE1:#[0-9]+]]
+
+// CHECK: attributes [[ATTRFALSE]] = { {{.*}}"disable-tail-calls"="false"{{.*}} }
+// CHECK: attributes [[ATTRTRUE0]] = { {{.*}}"disable-tail-calls"="true"{{.*}} }
+// CHECK: attributes [[ATTRTRUE1]] = { {{.*}}"disable-tail-calls"="true"{{.*}} }
diff --git a/clang/test/Sema/attr-disable-tail-calls.c b/clang/test/Sema/attr-disable-tail-calls.c
new file mode 100644
index 00000000000..4574d5e0b66
--- /dev/null
+++ b/clang/test/Sema/attr-disable-tail-calls.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void __attribute__((disable_tail_calls,naked)) foo1(int a) { // expected-error {{'disable_tail_calls' and 'naked' attributes are not compatible}} expected-note {{conflicting attribute is here}}
+ __asm__("");
+}
+
+void __attribute__((naked,disable_tail_calls)) foo2(int a) { // expected-error {{'naked' and 'disable_tail_calls' attributes are not compatible}} expected-note {{conflicting attribute is here}}
+ __asm__("");
+}
+
+int g0 __attribute__((disable_tail_calls)); // expected-warning {{'disable_tail_calls' attribute only applies to functions and methods}}
+
+int foo3(int a) __attribute__((disable_tail_calls("abc"))); // expected-error {{'disable_tail_calls' attribute takes no arguments}}
diff --git a/clang/test/SemaCXX/attr-disable-tail-calls.cpp b/clang/test/SemaCXX/attr-disable-tail-calls.cpp
new file mode 100644
index 00000000000..d442aa6d440
--- /dev/null
+++ b/clang/test/SemaCXX/attr-disable-tail-calls.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+class B {
+public:
+ [[clang::disable_tail_calls]] virtual int foo1() { return 1; }
+ [[clang::disable_tail_calls]] int foo2() { return 2; }
+};
OpenPOWER on IntegriCloud