summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaObjCXX
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2017-09-20 06:22:51 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2017-09-20 06:22:51 +0000
commitfc587e6a570796ca321aa981866359c3ae13e21e (patch)
treef99180094d880f13e2267ac280df889296bae3db /clang/test/SemaObjCXX
parentc8aea66627095ecff057958e06c43b4225b5bf95 (diff)
downloadbcm5719-llvm-fc587e6a570796ca321aa981866359c3ae13e21e.tar.gz
bcm5719-llvm-fc587e6a570796ca321aa981866359c3ae13e21e.zip
Add support for attribute 'noescape'.
The attribute informs the compiler that the annotated pointer parameter of a function cannot escape and enables IRGen to attach attribute 'nocapture' to parameters that are annotated with the attribute. That is the only optimization that currently takes advantage of 'noescape', but there are other optimizations that will be added later that improves IRGen for ObjC blocks. rdar://problem/19886775 Differential Revision: https://reviews.llvm.org/D32520 llvm-svn: 313720
Diffstat (limited to 'clang/test/SemaObjCXX')
-rw-r--r--clang/test/SemaObjCXX/noescape.mm90
1 files changed, 90 insertions, 0 deletions
diff --git a/clang/test/SemaObjCXX/noescape.mm b/clang/test/SemaObjCXX/noescape.mm
new file mode 100644
index 00000000000..6c5d9897aaf
--- /dev/null
+++ b/clang/test/SemaObjCXX/noescape.mm
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++1z %s
+
+typedef void (^BlockTy)();
+
+struct S {
+ int i;
+ void m();
+};
+
+void noescapeFunc0(id, __attribute__((noescape)) BlockTy);
+void noescapeFunc1(id, [[clang::noescape]] BlockTy);
+void noescapeFunc2(__attribute__((noescape)) int *); // expected-note {{previous declaration is here}}
+void noescapeFunc3(__attribute__((noescape)) id);
+void noescapeFunc4(__attribute__((noescape)) int &);
+void noescapeFunc2(int *); // expected-error {{conflicting types for 'noescapeFunc2'}}
+
+void invalidFunc0(int __attribute__((noescape))); // expected-warning {{'noescape' attribute only applies to pointer arguments}}
+void invalidFunc1(int __attribute__((noescape(0)))); // expected-error {{'noescape' attribute takes no arguments}}
+void invalidFunc2(int0 *__attribute__((noescape))); // expected-error {{use of undeclared identifier 'int0'; did you mean 'int'?}}
+void invalidFunc3(__attribute__((noescape)) int (S::*Ty)); // expected-warning {{'noescape' attribute only applies to pointer arguments}}
+void invalidFunc4(__attribute__((noescape)) void (S::*Ty)()); // expected-warning {{'noescape' attribute only applies to pointer arguments}}
+int __attribute__((noescape)) g; // expected-warning {{'noescape' attribute only applies to parameters}}
+
+struct S1 {
+ virtual void m0(int *__attribute__((noescape))); // expected-note {{parameter of overridden method is annotated with __attribute__((noescape))}}
+};
+
+struct S2 : S1 {
+ void m0(int *__attribute__((noescape))) override;
+};
+
+struct S3 : S1 {
+ void m0(int *) override; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}}
+};
+
+__attribute__((objc_root_class))
+@interface C0
+-(void) m0:(int*)__attribute__((noescape)) p; // expected-note {{parameter of overridden method is annotated with __attribute__((noescape))}}
+@end
+
+@implementation C0
+-(void) m0:(int*)__attribute__((noescape)) p {}
+@end
+
+@interface C1 : C0
+-(void) m0:(int*)__attribute__((noescape)) p;
+@end
+
+@implementation C1 : C0
+-(void) m0:(int*)__attribute__((noescape)) p {}
+@end
+
+@interface C2 : C0
+-(void) m0:(int*) p; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}}
+@end
+
+@implementation C2 : C0
+-(void) m0:(int*) p {}
+@end
+
+void func0(int *);
+void (*fnptr0)(int *);
+void (*fnptr1)(__attribute__((noescape)) int *);
+template<void (*fn)(int*)> struct S4 {};
+template<void (*fn)(int* __attribute__((noescape)))> struct S5 {};
+
+#if __cplusplus < 201406
+ // expected-note@-4 {{template parameter is declared here}}
+ // expected-note@-4 {{template parameter is declared here}}
+#endif
+
+void test0() {
+ fnptr0 = &func0;
+ fnptr0 = &noescapeFunc2;
+ fnptr1 = &func0; // expected-error {{assigning to 'void (*)(__attribute__((noescape)) int *)' from incompatible type 'void (*)(int *)'}}
+ fnptr1 = &noescapeFunc2;
+ S4<&func0> e0;
+ S4<&noescapeFunc2> e1;
+ S5<&func0> ne0;
+
+#if __cplusplus < 201406
+ // expected-error@-4 {{non-type template argument of type 'void (*)(__attribute__((noescape)) int *)' cannot be converted to a value of type 'void (*)(int *)'}}
+ // expected-error@-4 {{non-type template argument of type 'void (*)(int *)' cannot be converted to a value of type 'void (*)(__attribute__((noescape)) int *)'}}
+#else
+ // expected-error@-6 {{value of type 'void (*)(int *)' is not implicitly convertible to 'void (*)(__attribute__((noescape)) int *)'}}
+#endif
+
+ S5<&noescapeFunc2> ne1;
+}
OpenPOWER on IntegriCloud