blob: a0b8467bcca3d3a23dc0ac009f3d2eb8dd4e713c [file] [log] [blame]
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s
// Need std::initializer_list
namespace std {
typedef decltype(sizeof(int)) size_t;
// libc++'s implementation
template <class _E>
class initializer_list
{
const _E* __begin_;
size_t __size_;
initializer_list(const _E* __b, size_t __s)
: __begin_(__b),
__size_(__s)
{}
public:
typedef _E value_type;
typedef const _E& reference;
typedef const _E& const_reference;
typedef size_t size_type;
typedef const _E* iterator;
typedef const _E* const_iterator;
initializer_list() : __begin_(nullptr), __size_(0) {}
size_t size() const {return __size_;}
const _E* begin() const {return __begin_;}
const _E* end() const {return __begin_ + __size_;}
};
}
// Declaration syntax checks
[[]] int before_attr;
int [[]] between_attr;
const [[]] int between_attr_2 = 0; // expected-error {{an attribute list cannot appear here}}
int after_attr [[]];
int * [[]] ptr_attr;
int & [[]] ref_attr = after_attr;
int && [[]] rref_attr = 0;
int array_attr [1] [[]];
alignas(8) int aligned_attr;
[[test::valid(for 42 [very] **** '+' symbols went on a trip and had a "good"_time; the end.)]]
int garbage_attr;
[[,,,static, class, namespace,, inline, constexpr, mutable,, bi\
tand, bitor::compl(!.*_ Cx.!U^*R),,,]] int more_garbage_attr;
[[u8"invalid!"]] int invalid_string_attr; // expected-error {{expected ']'}}
void fn_attr () [[]];
void noexcept_fn_attr () noexcept [[]];
struct MemberFnOrder {
virtual void f() const volatile && noexcept [[]] final = 0;
};
struct [[]] struct_attr;
class [[]] class_attr {};
union [[]] union_attr;
[[]] struct with_init_declarators {} init_declarator;
[[]] struct no_init_declarators; // expected-error {{an attribute list cannot appear here}}
[[]];
struct ctordtor {
[[]] ctordtor();
[[]] ~ctordtor();
};
[[]] ctordtor::ctordtor() {}
[[]] ctordtor::~ctordtor() {}
extern "C++" [[]] int extern_attr;
template <typename T> [[]] void template_attr ();
[[]] [[]] int [[]] [[]] multi_attr [[]] [[]];
int comma_attr [[,]];
int scope_attr [[foo::]]; // expected-error {{expected identifier}}
int (paren_attr) [[]]; // expected-error {{an attribute list cannot appear here}}
unsigned [[]] int attr_in_decl_spec; // expected-error {{an attribute list cannot appear here}}
unsigned [[]] int [[]] const double_decl_spec = 0; // expected-error 2{{an attribute list cannot appear here}}
class foo {
void const_after_attr () [[]] const; // expected-error {{expected ';'}}
};
extern "C++" [[]] { } // expected-error {{an attribute list cannot appear here}}
[[]] template <typename T> void before_template_attr (); // expected-error {{an attribute list cannot appear here}}
[[]] namespace ns { int i; } // expected-error {{an attribute list cannot appear here}} expected-note {{declared here}}
[[]] static_assert(true, ""); //expected-error {{an attribute list cannot appear here}}
[[]] asm(""); // expected-error {{an attribute list cannot appear here}}
[[]] using ns::i; // expected-error {{an attribute list cannot appear here}}
[[]] using namespace ns;
[[]] using T = int; // expected-error {{an attribute list cannot appear here}}
using T [[]] = int; // ok
template<typename T> using U [[]] = T;
using ns::i [[]]; // expected-error {{an attribute list cannot appear here}}
using [[]] ns::i; // expected-error {{an attribute list cannot appear here}}
auto trailing() -> [[]] const int; // expected-error {{an attribute list cannot appear here}}
auto trailing() -> const [[]] int; // expected-error {{an attribute list cannot appear here}}
auto trailing() -> const int [[]];
auto trailing_2() -> struct struct_attr [[]];
namespace N {
struct S {};
};
template<typename> struct Template {};
// FIXME: Improve this diagnostic
struct [[]] N::S s; // expected-error {{an attribute list cannot appear here}}
struct [[]] Template<int> t; // expected-error {{an attribute list cannot appear here}}
struct [[]] ::template Template<int> u; // expected-error {{an attribute list cannot appear here}}
template struct [[]] Template<char>; // expected-error {{an attribute list cannot appear here}}
template <> struct [[]] Template<void>;
enum [[]] E1 {};
enum [[]] E2; // expected-error {{forbids forward references}}
enum [[]] E1;
enum [[]] E3 : int;
enum [[]] {
k_123 [[]] = 123 // expected-error {{an attribute list cannot appear here}}
};
enum [[]] E1 e; // expected-error {{an attribute list cannot appear here}}
enum [[]] class E4 { }; // expected-error {{an attribute list cannot appear here}}
enum struct [[]] E5;
struct S {
friend int f [[]] (); // expected-FIXME{{an attribute list cannot appear here}}
[[]] friend int g(); // expected-FIXME{{an attribute list cannot appear here}}
[[]] friend int h() {
}
friend class [[]] C; // expected-error{{an attribute list cannot appear here}}
};
template<typename T> void tmpl(T) {}
template void tmpl [[]] (int); // expected-FIXME {{an attribute list cannot appear here}}
template [[]] void tmpl(char); // expected-error {{an attribute list cannot appear here}}
template void [[]] tmpl(short);
// Argument tests
alignas int aligned_no_params; // expected-error {{expected '('}}
alignas(i) int aligned_nonconst; // expected-error {{'aligned' attribute requires integer constant}} expected-note {{read of non-const variable 'i'}}
// Statement tests
void foo () {
[[]] ;
[[]] { }
[[]] if (0) { }
[[]] for (;;);
[[]] do {
[[]] continue;
} while (0);
[[]] while (0);
[[]] switch (i) {
[[]] case 0:
[[]] default:
[[]] break;
}
[[]] goto there;
[[]] there:
[[]] try {
} [[]] catch (...) { // expected-error {{an attribute list cannot appear here}}
}
struct S { int arr[2]; } s;
(void)s.arr[ [] { return 0; }() ]; // expected-error {{C++11 only allows consecutive left square brackets when introducing an attribute}}
int n = __builtin_offsetof(S, arr[ [] { return 0; }() ]); // expected-error {{C++11 only allows consecutive left square brackets when introducing an attribute}}
void bar [[noreturn]] ([[]] int i, [[]] int j);
using FuncType = void ([[]] int);
void baz([[]]...); // expected-error {{expected parameter declarator}}
[[]] return;
}
template<typename...Ts> void variadic() {
void bar [[noreturn...]] (); // expected-error {{attribute 'noreturn' cannot be used as an attribute pack}}
}
// Expression tests
void bar () {
[] () [[noreturn]] { return; } (); // expected-error {{should not return}}
[] () [[noreturn]] { throw; } ();
new int[42][[]][5][[]]{};
}
// Condition tests
void baz () {
if ([[]] bool b = true) {
switch ([[]] int n { 42 }) {
default:
for ([[]] int n = 0; [[]] char b = n < 5; ++b) {
}
}
}
int x;
// An attribute can be applied to an expression-statement, such as the first
// statement in a for. But it can't be applied to a condition which is an
// expression.
for ([[]] x = 0; ; ) {} // expected-error {{an attribute list cannot appear here}}
for (; [[]] x < 5; ) {} // expected-error {{an attribute list cannot appear here}}
while ([[]] bool k { false }) {
}
while ([[]] true) { // expected-error {{an attribute list cannot appear here}}
}
do {
} while ([[]] false); // expected-error {{an attribute list cannot appear here}}
for ([[]] int n : { 1, 2, 3 }) {
}
}
enum class __attribute__((visibility("hidden"))) SecretKeepers {
one, /* rest are deprecated */ two, three
};
enum class [[]] EvenMoreSecrets {};