cxx0x-attributes.cpp revision f7a052732c2b6c82f74708038f75fa92c9b4dba0
1// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s
2
3// Need std::initializer_list
4namespace std {
5  typedef decltype(sizeof(int)) size_t;
6
7  // libc++'s implementation
8  template <class _E>
9  class initializer_list
10  {
11    const _E* __begin_;
12    size_t    __size_;
13
14    initializer_list(const _E* __b, size_t __s)
15      : __begin_(__b),
16        __size_(__s)
17    {}
18
19  public:
20    typedef _E        value_type;
21    typedef const _E& reference;
22    typedef const _E& const_reference;
23    typedef size_t    size_type;
24
25    typedef const _E* iterator;
26    typedef const _E* const_iterator;
27
28    initializer_list() : __begin_(nullptr), __size_(0) {}
29
30    size_t    size()  const {return __size_;}
31    const _E* begin() const {return __begin_;}
32    const _E* end()   const {return __begin_ + __size_;}
33  };
34}
35
36
37// Declaration syntax checks
38[[]] int before_attr;
39int [[]] between_attr;
40const [[]] int between_attr_2 = 0; // expected-error {{an attribute list cannot appear here}}
41int after_attr [[]];
42int * [[]] ptr_attr;
43int & [[]] ref_attr = after_attr;
44int && [[]] rref_attr = 0;
45int array_attr [1] [[]];
46alignas(8) int aligned_attr;
47[[test::valid(for 42 [very] **** '+' symbols went on a trip and had a "good"_time; the end.)]] int garbage_attr; // expected-warning {{unknown attribute 'valid' ignored}}
48[[,,,static, class, namespace,, inline, constexpr, mutable,, bitand, bitor::compl(!.*_ Cx.!U^*R),,,]] int more_garbage_attr; // expected-warning {{unknown attribute 'static' ignored}} \
49	// expected-warning {{unknown attribute 'class' ignored}} \
50	// expected-warning {{unknown attribute 'namespace' ignored}} \
51	// expected-warning {{unknown attribute 'inline' ignored}} \
52	// expected-warning {{unknown attribute 'constexpr' ignored}} \
53	// expected-warning {{unknown attribute 'mutable' ignored}} \
54	// expected-warning {{unknown attribute 'bitand' ignored}} \
55        // expected-warning {{unknown attribute 'compl' ignored}}
56[[u8"invalid!"]] int invalid_string_attr; // expected-error {{expected ']'}}
57void fn_attr () [[]];
58void noexcept_fn_attr () noexcept [[]];
59struct MemberFnOrder {
60  virtual void f() const volatile && noexcept [[]] final = 0;
61};
62struct [[]] struct_attr;
63class [[]] class_attr {};
64union [[]] union_attr;
65
66// Checks attributes placed at wrong syntactic locations of class specifiers.
67class [[]] [[]]
68  attr_after_class_name_decl [[]] [[]]; // expected-error {{an attribute list cannot appear here}}
69
70class [[]] [[]]
71 attr_after_class_name_definition [[]] [[]] [[]]{}; // expected-error {{an attribute list cannot appear here}}
72
73class [[]] c {};
74class c [[]] [[]] x;
75class c [[]] [[]] y [[]] [[]];
76class c final [(int){0}];
77
78class base {};
79class [[]] [[]] final_class
80  alignas(float) [[]] final // expected-error {{an attribute list cannot appear here}}
81  alignas(float) [[]] [[]] alignas(float): base{}; // expected-error {{an attribute list cannot appear here}}
82
83class [[]] [[]] final_class_another
84  [[]] [[]] alignas(16) final // expected-error {{an attribute list cannot appear here}}
85  [[]] [[]] alignas(16) [[]]{}; // expected-error {{an attribute list cannot appear here}}
86
87[[]] struct with_init_declarators {} init_declarator;
88[[]] struct no_init_declarators; // expected-error {{an attribute list cannot appear here}}
89[[]];
90struct ctordtor {
91  [[]] ctordtor();
92  [[]] ~ctordtor();
93};
94[[]] ctordtor::ctordtor() {}
95[[]] ctordtor::~ctordtor() {}
96extern "C++" [[]] int extern_attr;
97template <typename T> [[]] void template_attr ();
98[[]] [[]] int [[]] [[]] multi_attr [[]] [[]];
99
100int comma_attr [[,]];
101int scope_attr [[foo::]]; // expected-error {{expected identifier}}
102int (paren_attr) [[]]; // expected-error {{an attribute list cannot appear here}}
103unsigned [[]] int attr_in_decl_spec; // expected-error {{an attribute list cannot appear here}}
104unsigned [[]] int [[]] const double_decl_spec = 0; // expected-error 2{{an attribute list cannot appear here}}
105class foo {
106  void const_after_attr () [[]] const; // expected-error {{expected ';'}}
107};
108extern "C++" [[]] { } // expected-error {{an attribute list cannot appear here}}
109[[]] template <typename T> void before_template_attr (); // expected-error {{an attribute list cannot appear here}}
110[[]] namespace ns { int i; } // expected-error {{an attribute list cannot appear here}} expected-note {{declared here}}
111[[]] static_assert(true, ""); //expected-error {{an attribute list cannot appear here}}
112[[]] asm(""); // expected-error {{an attribute list cannot appear here}}
113
114[[]] using ns::i; // expected-error {{an attribute list cannot appear here}}
115[[]] using namespace ns;
116
117[[]] using T = int; // expected-error {{an attribute list cannot appear here}}
118using T [[]] = int; // ok
119template<typename T> using U [[]] = T;
120using ns::i [[]]; // expected-error {{an attribute list cannot appear here}}
121using [[]] ns::i; // expected-error {{an attribute list cannot appear here}}
122
123auto trailing() -> [[]] const int; // expected-error {{an attribute list cannot appear here}}
124auto trailing() -> const [[]] int; // expected-error {{an attribute list cannot appear here}}
125auto trailing() -> const int [[]];
126auto trailing_2() -> struct struct_attr [[]];
127
128namespace N {
129  struct S {};
130};
131template<typename> struct Template {};
132
133// FIXME: Improve this diagnostic
134struct [[]] N::S s; // expected-error {{an attribute list cannot appear here}}
135struct [[]] Template<int> t; // expected-error {{an attribute list cannot appear here}}
136struct [[]] ::template Template<int> u; // expected-error {{an attribute list cannot appear here}}
137template struct [[]] Template<char>; // expected-error {{an attribute list cannot appear here}}
138template <> struct [[]] Template<void>;
139
140enum [[]] E1 {};
141enum [[]] E2; // expected-error {{forbids forward references}}
142enum [[]] E1;
143enum [[]] E3 : int;
144enum [[]] {
145  k_123 [[]] = 123 // expected-error {{an attribute list cannot appear here}}
146};
147enum [[]] E1 e; // expected-error {{an attribute list cannot appear here}}
148enum [[]] class E4 { }; // expected-error {{an attribute list cannot appear here}}
149enum struct [[]] E5;
150
151struct S {
152  friend int f [[]] (); // expected-FIXME{{an attribute list cannot appear here}}
153  friend int f1 [[noreturn]] (); //expected-error{{an attribute list cannot appear here}}
154  friend int f2 [[]] [[noreturn]] () {}
155  [[]] friend int g(); // expected-error{{an attribute list cannot appear here}}
156  [[]] friend int h() {
157  }
158  [[]] friend int f3(), f4(), f5(); // expected-error{{an attribute list cannot appear here}}
159  friend int f6 [[noreturn]] (), f7 [[noreturn]] (), f8 [[noreturn]] (); // expected-error3 {{an attribute list cannot appear here}}
160  friend class [[]] C; // expected-error{{an attribute list cannot appear here}}
161  [[]] friend class D; // expected-error{{an attribute list cannot appear here}}
162  [[]] friend int; // expected-error{{an attribute list cannot appear here}}
163};
164template<typename T> void tmpl(T) {}
165template void tmpl [[]] (int); // expected-FIXME {{an attribute list cannot appear here}}
166template [[]] void tmpl(char); // expected-error {{an attribute list cannot appear here}}
167template void [[]] tmpl(short);
168
169// Argument tests
170alignas int aligned_no_params; // expected-error {{expected '('}}
171alignas(i) int aligned_nonconst; // expected-error {{'aligned' attribute requires integer constant}} expected-note {{read of non-const variable 'i'}}
172
173// Statement tests
174void foo () {
175  [[]] ;
176  [[]] { }
177  [[]] if (0) { }
178  [[]] for (;;);
179  [[]] do {
180    [[]] continue;
181  } while (0);
182  [[]] while (0);
183
184  [[]] switch (i) {
185    [[]] case 0:
186    [[]] default:
187      [[]] break;
188  }
189
190  [[]] goto there;
191  [[]] there:
192
193  [[]] try {
194  } [[]] catch (...) { // expected-error {{an attribute list cannot appear here}}
195  }
196  struct S { int arr[2]; } s;
197  (void)s.arr[ [] { return 0; }() ]; // expected-error {{C++11 only allows consecutive left square brackets when introducing an attribute}}
198  int n = __builtin_offsetof(S, arr[ [] { return 0; }() ]); // expected-error {{C++11 only allows consecutive left square brackets when introducing an attribute}}
199
200  void bar [[noreturn]] ([[]] int i, [[]] int j);
201  using FuncType = void ([[]] int);
202  void baz([[]]...); // expected-error {{expected parameter declarator}}
203
204  [[]] return;
205}
206
207template<typename...Ts> void variadic() {
208  void bar [[noreturn...]] (); // expected-error {{attribute 'noreturn' cannot be used as an attribute pack}}
209}
210
211// Expression tests
212void bar () {
213  [] () [[noreturn]] { return; } (); // expected-error {{should not return}}
214  [] () [[noreturn]] { throw; } ();
215  new int[42][[]][5][[]]{};
216}
217
218// Condition tests
219void baz () {
220  if ([[]] bool b = true) {
221    switch ([[]] int n { 42 }) {
222    default:
223      for ([[]] int n = 0; [[]] char b = n < 5; ++b) {
224      }
225    }
226  }
227  int x;
228  // An attribute can be applied to an expression-statement, such as the first
229  // statement in a for. But it can't be applied to a condition which is an
230  // expression.
231  for ([[]] x = 0; ; ) {} // expected-error {{an attribute list cannot appear here}}
232  for (; [[]] x < 5; ) {} // expected-error {{an attribute list cannot appear here}}
233  while ([[]] bool k { false }) {
234  }
235  while ([[]] true) { // expected-error {{an attribute list cannot appear here}}
236  }
237  do {
238  } while ([[]] false); // expected-error {{an attribute list cannot appear here}}
239
240  for ([[]] int n : { 1, 2, 3 }) {
241  }
242}
243
244enum class __attribute__((visibility("hidden"))) SecretKeepers {
245  one, /* rest are deprecated */ two, three
246};
247enum class [[]] EvenMoreSecrets {};
248
249namespace arguments {
250  void f[[gnu::format(printf, 1, 2)]](const char*, ...);
251  void g() [[unknown::foo(currently arguments of attributes from unknown namespace other than 'gnu' namespace are ignored... blah...)]]; // expected-warning {{unknown attribute 'foo' ignored}}
252}
253
254// Forbid attributes on decl specifiers.
255unsigned [[gnu::used]] static int [[gnu::unused]] v1; // expected-warning {{attribute 'unused' ignored, because it is not attached to a declaration}} \
256           expected-error {{an attribute list cannot appear here}}
257typedef [[gnu::used]] unsigned long [[gnu::unused]] v2; // expected-warning {{attribute 'unused' ignored, because it is not attached to a declaration}} \
258          expected-error {{an attribute list cannot appear here}}
259int [[carries_dependency]] foo(int [[carries_dependency]] x); // expected-warning 2{{attribute 'carries_dependency' ignored, because it is not attached to a declaration}}
260
261// Forbid [[gnu::...]] attributes on declarator chunks.
262int *[[gnu::unused]] v3; // expected-warning {{attribute 'unused' ignored}}
263int v4[2][[gnu::unused]]; // expected-warning {{attribute 'unused' ignored}}
264int v5()[[gnu::unused]]; // expected-warning {{attribute 'unused' ignored}}
265