summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp1
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp1
-rw-r--r--clang/test/PCH/no-escaping-block-tail-calls.cpp14
-rw-r--r--clang/test/PCH/no-escaping-block-tail-calls.h16
4 files changed, 32 insertions, 0 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 5605201a509..d17ec8e0461 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1472,6 +1472,7 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
BD->setIsVariadic(Record.readInt());
BD->setBlockMissingReturnType(Record.readInt());
BD->setIsConversionFromLambda(Record.readInt());
+ BD->setDoesNotEscape(Record.readInt());
bool capturesCXXThis = Record.readInt();
unsigned numCaptures = Record.readInt();
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 3250a2e6bbb..d83ac65e78c 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1097,6 +1097,7 @@ void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
Record.push_back(D->isVariadic());
Record.push_back(D->blockMissingReturnType());
Record.push_back(D->isConversionFromLambda());
+ Record.push_back(D->doesNotEscape());
Record.push_back(D->capturesCXXThis());
Record.push_back(D->getNumCaptures());
for (const auto &capture : D->captures()) {
diff --git a/clang/test/PCH/no-escaping-block-tail-calls.cpp b/clang/test/PCH/no-escaping-block-tail-calls.cpp
new file mode 100644
index 00000000000..1e38d45f624
--- /dev/null
+++ b/clang/test/PCH/no-escaping-block-tail-calls.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -x c++-header -emit-pch -O1 -fblocks -fno-escaping-block-tail-calls -o %t %S/no-escaping-block-tail-calls.h
+// RUN: %clang_cc1 -include-pch %t -emit-llvm -O1 -fblocks -fno-escaping-block-tail-calls -o - %s | FileCheck %s
+
+// Check that -fno-escaping-block-tail-calls doesn't disable tail-call
+// optimization if the block is non-escaping.
+
+// CHECK-LABEL: define internal i32 @___ZN1S1mEv_block_invoke(
+// CHECK: %[[CALL:.*]] = tail call i32 @_ZN1S3fooER2S0(
+// CHECK-NEXT: ret i32 %[[CALL]]
+
+void test() {
+ S s;
+ s.m();
+}
diff --git a/clang/test/PCH/no-escaping-block-tail-calls.h b/clang/test/PCH/no-escaping-block-tail-calls.h
new file mode 100644
index 00000000000..5d37d904795
--- /dev/null
+++ b/clang/test/PCH/no-escaping-block-tail-calls.h
@@ -0,0 +1,16 @@
+typedef int (^BlockTy)(void);
+
+struct S0 {
+ int a;
+};
+
+struct S {
+ int i;
+ void func(BlockTy __attribute__((noescape)));
+ int foo(S0 &);
+
+ void m() {
+ __block S0 x;
+ func(^{ return foo(x); });
+ }
+};
OpenPOWER on IntegriCloud