annotate clang/test/SemaTemplate/attributes.cpp @ 207:2e18cbf3894f

LLVM12
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Jun 2021 06:07:14 +0900
parents 1d019706d866
children c4bab56944e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 // RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -verify %s
anatofuz
parents:
diff changeset
2 // RUN: not %clang_cc1 -std=gnu++11 -ast-dump %s | FileCheck %s
anatofuz
parents:
diff changeset
3
anatofuz
parents:
diff changeset
4 namespace attribute_aligned {
anatofuz
parents:
diff changeset
5 template<int N>
anatofuz
parents:
diff changeset
6 struct X {
anatofuz
parents:
diff changeset
7 char c[1] __attribute__((__aligned__((N)))); // expected-error {{alignment is not a power of 2}}
anatofuz
parents:
diff changeset
8 };
anatofuz
parents:
diff changeset
9
anatofuz
parents:
diff changeset
10 template <bool X> struct check {
anatofuz
parents:
diff changeset
11 int check_failed[X ? 1 : -1]; // expected-error {{array with a negative size}}
anatofuz
parents:
diff changeset
12 };
anatofuz
parents:
diff changeset
13
anatofuz
parents:
diff changeset
14 template <int N> struct check_alignment {
anatofuz
parents:
diff changeset
15 typedef check<N == sizeof(X<N>)> t; // expected-note {{in instantiation}}
anatofuz
parents:
diff changeset
16 };
anatofuz
parents:
diff changeset
17
anatofuz
parents:
diff changeset
18 check_alignment<1>::t c1;
anatofuz
parents:
diff changeset
19 check_alignment<2>::t c2;
anatofuz
parents:
diff changeset
20 check_alignment<3>::t c3; // expected-note 2 {{in instantiation}}
anatofuz
parents:
diff changeset
21 check_alignment<4>::t c4;
anatofuz
parents:
diff changeset
22
anatofuz
parents:
diff changeset
23 template<unsigned Size, unsigned Align>
anatofuz
parents:
diff changeset
24 class my_aligned_storage
anatofuz
parents:
diff changeset
25 {
anatofuz
parents:
diff changeset
26 __attribute__((aligned(Align))) char storage[Size];
anatofuz
parents:
diff changeset
27 };
anatofuz
parents:
diff changeset
28
anatofuz
parents:
diff changeset
29 template<typename T>
anatofuz
parents:
diff changeset
30 class C {
anatofuz
parents:
diff changeset
31 public:
anatofuz
parents:
diff changeset
32 C() {
anatofuz
parents:
diff changeset
33 static_assert(sizeof(t) == sizeof(T), "my_aligned_storage size wrong");
anatofuz
parents:
diff changeset
34 static_assert(alignof(t) == alignof(T), "my_aligned_storage align wrong"); // expected-warning{{'alignof' applied to an expression is a GNU extension}}
anatofuz
parents:
diff changeset
35 }
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 private:
anatofuz
parents:
diff changeset
38 my_aligned_storage<sizeof(T), alignof(T)> t;
anatofuz
parents:
diff changeset
39 };
anatofuz
parents:
diff changeset
40
anatofuz
parents:
diff changeset
41 C<double> cd;
anatofuz
parents:
diff changeset
42 }
anatofuz
parents:
diff changeset
43
anatofuz
parents:
diff changeset
44 namespace PR9049 {
anatofuz
parents:
diff changeset
45 extern const void *CFRetain(const void *ref);
anatofuz
parents:
diff changeset
46
anatofuz
parents:
diff changeset
47 template<typename T> __attribute__((cf_returns_retained))
anatofuz
parents:
diff changeset
48 inline T WBCFRetain(T aValue) { return aValue ? (T)CFRetain(aValue) : (T)0; }
anatofuz
parents:
diff changeset
49
anatofuz
parents:
diff changeset
50
anatofuz
parents:
diff changeset
51 extern void CFRelease(const void *ref);
anatofuz
parents:
diff changeset
52
anatofuz
parents:
diff changeset
53 template<typename T>
anatofuz
parents:
diff changeset
54 inline void WBCFRelease(__attribute__((cf_consumed)) T aValue) { if(aValue) CFRelease(aValue); }
anatofuz
parents:
diff changeset
55 }
anatofuz
parents:
diff changeset
56
anatofuz
parents:
diff changeset
57 // CHECK: FunctionTemplateDecl {{.*}} HasAnnotations
anatofuz
parents:
diff changeset
58 // CHECK: AnnotateAttr {{.*}} "ANNOTATE_FOO"
anatofuz
parents:
diff changeset
59 // CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR"
anatofuz
parents:
diff changeset
60 // CHECK: FunctionDecl {{.*}} HasAnnotations
anatofuz
parents:
diff changeset
61 // CHECK: TemplateArgument type 'int'
anatofuz
parents:
diff changeset
62 // CHECK: AnnotateAttr {{.*}} "ANNOTATE_FOO"
anatofuz
parents:
diff changeset
63 // CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR"
anatofuz
parents:
diff changeset
64 template<typename T> [[clang::annotate("ANNOTATE_FOO"), clang::annotate("ANNOTATE_BAR")]] void HasAnnotations();
anatofuz
parents:
diff changeset
65 void UseAnnotations() { HasAnnotations<int>(); }
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
66
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
67 namespace preferred_name {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
68 int x [[clang::preferred_name("frank")]]; // expected-error {{expected a type}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
69 int y [[clang::preferred_name(int)]]; // expected-warning {{'preferred_name' attribute only applies to class templates}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
70 struct [[clang::preferred_name(int)]] A; // expected-warning {{'preferred_name' attribute only applies to class templates}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
71 template<typename T> struct [[clang::preferred_name(int)]] B; // expected-error {{argument 'int' to 'preferred_name' attribute is not a typedef for a specialization of 'B'}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
72 template<typename T> struct C;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
73 using X = C<int>; // expected-note {{'X' declared here}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
74 typedef C<float> Y;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
75 using Z = const C<double>; // expected-note {{'Z' declared here}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
76 template<typename T> struct [[clang::preferred_name(C<int>)]] C; // expected-error {{argument 'C<int>' to 'preferred_name' attribute is not a typedef for a specialization of 'C'}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
77 template<typename T> struct [[clang::preferred_name(X), clang::preferred_name(Y)]] C;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
78 template<typename T> struct [[clang::preferred_name(const X)]] C; // expected-error {{argument 'const preferred_name::X'}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
79 template<typename T> struct [[clang::preferred_name(Z)]] C; // expected-error {{argument 'preferred_name::Z' (aka 'const C<double>')}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
80 template<typename T> struct C {};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
81
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
82 // CHECK: ClassTemplateDecl {{.*}} <line:[[@LINE-10]]:{{.*}} C
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
83 // CHECK: ClassTemplateSpecializationDecl {{.*}} struct C definition
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
84 // CHECK: TemplateArgument type 'int'
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
85 // CHECK-NOT: PreferredNameAttr
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
86 // CHECK: PreferredNameAttr {{.*}} preferred_name::X
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
87 // CHECK-NOT: PreferredNameAttr
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
88 // CHECK: CXXRecordDecl
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
89 // CHECK: ClassTemplateSpecializationDecl {{.*}} struct C definition
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
90 // CHECK: TemplateArgument type 'float'
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
91 // CHECK-NOT: PreferredNameAttr
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
92 // CHECK: PreferredNameAttr {{.*}} preferred_name::Y
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
93 // CHECK-NOT: PreferredNameAttr
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
94 // CHECK: CXXRecordDecl
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
95 // CHECK: ClassTemplateSpecializationDecl {{.*}} struct C definition
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
96 // CHECK: TemplateArgument type 'double'
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
97 // CHECK-NOT: PreferredNameAttr
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
98 // CHECK: CXXRecordDecl
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
99
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
100 // Check this doesn't cause us to instantiate the same attribute multiple times.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
101 C<float> *cf1;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
102 C<float> *cf2;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
103
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
104 void f(C<int> a, C<float> b, C<double> c) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
105 auto p = a;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
106 auto q = b;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
107 auto r = c;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
108 p.f(); // expected-error {{no member named 'f' in 'preferred_name::X'}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
109 q.f(); // expected-error {{no member named 'f' in 'preferred_name::Y'}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
110 r.f(); // expected-error {{no member named 'f' in 'preferred_name::C<double>'}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
111 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
112
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
113 template<typename T> struct D;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
114 using DInt = D<int>;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
115 template<typename T> struct __attribute__((__preferred_name__(DInt))) D {};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
116 template struct D<int>;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
117 int use_dint = D<int>().get(); // expected-error {{no member named 'get' in 'preferred_name::DInt'}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
118
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
119 template<typename T> struct MemberTemplate {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
120 template<typename U> struct Iter;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
121 using iterator = Iter<T>;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
122 using const_iterator = Iter<const T>;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
123 template<typename U>
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
124 struct [[clang::preferred_name(iterator),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
125 clang::preferred_name(const_iterator)]] Iter {};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
126 };
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
127 auto it = MemberTemplate<int>::Iter<const int>();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
128 int n = it; // expected-error {{no viable conversion from 'preferred_name::MemberTemplate<int>::const_iterator' to 'int'}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
129
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
130 template<int A, int B, typename ...T> struct Foo;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
131 template<typename ...T> using Bar = Foo<1, 2, T...>;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
132 template<int A, int B, typename ...T> struct [[clang::preferred_name(::preferred_name::Bar<T...>)]] Foo {};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
133 Foo<1, 2, int, float>::nosuch x; // expected-error {{no type named 'nosuch' in 'preferred_name::Bar<int, float>'}}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
134 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
135 ::preferred_name::Foo<1, 2, int, float>::nosuch x; // expected-error {{no type named 'nosuch' in 'preferred_name::Bar<int, float>'}}