2016-03-08 08:32:55 +08:00
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -Wc++14-compat -Wc++14-extensions -Wc++1z-extensions %s
2009-11-21 16:43:09 +08:00
2012-06-23 13:07:58 +08:00
// 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_ ; }
} ;
}
2009-11-21 16:43:09 +08:00
// Declaration syntax checks
[ [ ] ] int before_attr ;
2011-09-30 02:03:57 +08:00
int [ [ ] ] between_attr ;
2012-06-23 13:07:58 +08:00
const [ [ ] ] int between_attr_2 = 0 ; // expected-error {{an attribute list cannot appear here}}
2009-11-21 16:43:09 +08:00
int after_attr [ [ ] ] ;
int * [ [ ] ] ptr_attr ;
2012-04-10 09:32:12 +08:00
int & [ [ ] ] ref_attr = after_attr ;
2013-02-21 03:22:51 +08:00
int & [[unknown]] ref_attr_2 = after_attr ; // expected-warning {{unknown attribute 'unknown' ignored}}
int & [[noreturn]] ref_attr_3 = after_attr ; // expected-error {{'noreturn' attribute cannot be applied to types}}
2012-04-10 09:32:12 +08:00
int & & [ [ ] ] rref_attr = 0 ;
2009-11-21 16:43:09 +08:00
int array_attr [ 1 ] [ [ ] ] ;
2011-09-30 02:04:28 +08:00
alignas ( 8 ) int aligned_attr ;
2012-10-03 09:56:22 +08:00
[[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}}
[[,,,static, class, namespace,, inline, constexpr, mutable,, bitand, bitor::compl(!.*_ Cx.!U^*R),,,]] int more_garbage_attr ; / / expected - warning { { unknown attribute ' static ' ignored } } \
2014-04-01 01:32:39 +08:00
/ / expected - warning { { unknown attribute ' class ' ignored } } \
/ / expected - warning { { unknown attribute ' namespace ' ignored } } \
/ / expected - warning { { unknown attribute ' inline ' ignored } } \
/ / expected - warning { { unknown attribute ' constexpr ' ignored } } \
/ / expected - warning { { unknown attribute ' mutable ' ignored } } \
/ / expected - warning { { unknown attribute ' bitand ' ignored } } \
// expected-warning {{unknown attribute 'compl' ignored}}
2012-04-10 11:25:07 +08:00
[[u8"invalid!"]] int invalid_string_attr ; // expected-error {{expected ']'}}
2009-11-21 16:43:09 +08:00
void fn_attr ( ) [ [ ] ] ;
2012-04-10 09:32:12 +08:00
void noexcept_fn_attr ( ) noexcept [ [ ] ] ;
struct MemberFnOrder {
virtual void f ( ) const volatile & & noexcept [ [ ] ] final = 0 ;
} ;
2012-06-23 13:07:58 +08:00
struct [ [ ] ] struct_attr ;
2009-11-21 16:43:09 +08:00
class [ [ ] ] class_attr { } ;
2012-06-23 13:07:58 +08:00
union [ [ ] ] union_attr ;
2012-11-27 06:54:45 +08:00
// Checks attributes placed at wrong syntactic locations of class specifiers.
class [[]] [[]]
attr_after_class_name_decl [[]] [[]] ; // expected-error {{an attribute list cannot appear here}}
class [[]] [[]]
attr_after_class_name_definition [[]] [[]] [[]] { } ; // expected-error {{an attribute list cannot appear here}}
class [ [ ] ] c { } ;
class c [[]] [[]] x ;
class c [[]] [[]] y [[]] [[]] ;
class c final [ ( int ) { 0 } ] ;
class base { } ;
2013-11-28 02:53:58 +08:00
class [[]] [[]] final_class
2012-11-27 06:54:45 +08:00
alignas ( float ) [ [ ] ] final // expected-error {{an attribute list cannot appear here}}
alignas ( float ) [[]] [[]] alignas ( float ) : base { } ; // expected-error {{an attribute list cannot appear here}}
2013-11-28 02:53:58 +08:00
class [[]] [[]] final_class_another
2012-11-27 06:54:45 +08:00
[[]] [[]] alignas ( 16 ) final // expected-error {{an attribute list cannot appear here}}
[[]] [[]] alignas(16) [[]] { } ; // expected-error {{an attribute list cannot appear here}}
2014-12-30 05:56:22 +08:00
// The diagnostics here don't matter much, this just shouldn't crash:
class C final [[deprecated(l]] { } ) ; // expected-error {{use of undeclared identifier}} expected-error {{expected ']'}} expected-error {{an attribute list cannot appear here}} expected-error {{expected unqualified-id}}
class D final alignas ( [ l ) { } ] { } ) ; // expected-error {{expected ',' or ']' in lambda capture list}} expected-error {{an attribute list cannot appear here}}
2012-06-23 13:07:58 +08:00
[ [ ] ] struct with_init_declarators { } init_declarator ;
[ [ ] ] struct no_init_declarators ; // expected-error {{an attribute list cannot appear here}}
2013-02-22 17:06:26 +08:00
template < typename > [ [ ] ] struct no_init_declarators_template ; // expected-error {{an attribute list cannot appear here}}
void fn_with_structs ( ) {
[ [ ] ] struct with_init_declarators { } init_declarator ;
[ [ ] ] struct no_init_declarators ; // expected-error {{an attribute list cannot appear here}}
}
2012-06-23 13:07:58 +08:00
[ [ ] ] ;
struct ctordtor {
2017-02-08 09:16:55 +08:00
[[]] ctordtor [[]] () [[]] ;
ctordtor ( C ) [ [ ] ] ;
[[]] ~ctordtor [[]] () [[]] ;
2012-06-23 13:07:58 +08:00
} ;
2017-02-08 09:16:55 +08:00
[[]] ctordtor::ctordtor [[]] () [[]] { }
[[]] ctordtor::ctordtor (C) [[]] try { } catch ( . . . ) { }
[[]] ctordtor::~ctordtor [[]] () [[]] { }
2009-11-21 16:43:09 +08:00
extern " C++ " [ [ ] ] int extern_attr ;
template < typename T > [ [ ] ] void template_attr ( ) ;
2011-09-30 02:04:05 +08:00
[[]] [[]] int [[]] [[]] multi_attr [[]] [[]] ;
2009-11-21 16:43:09 +08:00
2012-04-10 11:25:07 +08:00
int comma_attr [[,]] ;
2009-11-21 16:43:09 +08:00
int scope_attr [[foo::]] ; // expected-error {{expected identifier}}
2012-04-10 09:32:12 +08:00
int ( paren_attr ) [ [ ] ] ; // expected-error {{an attribute list cannot appear here}}
2012-06-23 13:07:58 +08:00
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}}
2009-11-21 16:43:09 +08:00
class foo {
2012-04-10 09:32:12 +08:00
void const_after_attr ( ) [ [ ] ] const ; // expected-error {{expected ';'}}
2009-11-21 16:43:09 +08:00
} ;
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}}
2012-02-04 17:53:13 +08:00
[ [ ] ] namespace ns { int i ; } // expected-error {{an attribute list cannot appear here}} expected-note {{declared here}}
2009-11-21 16:43:09 +08:00
[ [ ] ] 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}}
2013-02-21 03:22:51 +08:00
[[unknown]] using namespace ns ; // expected-warning {{unknown attribute 'unknown' ignored}}
2013-11-28 02:53:58 +08:00
[[noreturn]] using namespace ns ; // expected-error {{'noreturn' attribute only applies to functions}}
2014-11-09 01:07:15 +08:00
namespace [ [ ] ] ns2 { } // expected-warning {{attributes on a namespace declaration are incompatible with C++ standards before C++1z}}
2009-11-21 16:43:09 +08:00
2013-10-15 09:34:54 +08:00
using [[]] alignas(4) [[]] ns : : i ; // expected-error {{an attribute list cannot appear here}}
using [[]] alignas(4) [[]] foobar = int ; // expected-error {{an attribute list cannot appear here}} expected-error {{'alignas' attribute only applies to}}
void bad_attributes_in_do_while ( ) {
do { } while (
[ [ ns : : i ) ; / / expected - error { { expected ' ] ' } } \
/ / expected - note { { to match this ' [ ' } } \
// expected-error {{expected expression}}
do { } while (
[ [ a ] b ns : : i ) ; / / expected - error { { expected ' ] ' } } \
/ / expected - note { { to match this ' [ ' } } \
// expected-error {{expected expression}}
do { } while (
[ [ ab ] ab ] ns : : i ) ; // expected-error {{an attribute list cannot appear here}}
do { } while ( // expected-note {{to match this '('}}
alignas ( 4 ns : : i ; // expected-note {{to match this '('}}
} // expected-error 2{{expected ')'}} expected-error {{expected expression}}
2012-06-23 13:07:58 +08:00
[ [ ] ] 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}}
2013-02-21 03:22:51 +08:00
using T [[unknown]] = int ; // expected-warning {{unknown attribute 'unknown' ignored}}
2013-11-28 02:53:58 +08:00
using T [[noreturn]] = int ; // expected-error {{'noreturn' attribute only applies to functions}}
2013-02-21 03:22:51 +08:00
using V = int ; // expected-note {{previous}}
using V [[gnu::vector_size(16)]] = int ; // expected-error {{redefinition with different types}}
2012-06-23 13:07:58 +08:00
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 [ [ ] ] {
2014-11-09 01:07:15 +08:00
k_123 [ [ ] ] = 123 // expected-warning {{attributes on an enumerator declaration are incompatible with C++ standards before C++1z}}
2012-06-23 13:07:58 +08:00
} ;
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}}
2012-11-29 07:17:40 +08:00
friend int f1 [[noreturn]] ( ) ; //expected-error{{an attribute list cannot appear here}}
friend int f2 [[]] [[noreturn]] ( ) { }
[ [ ] ] friend int g ( ) ; // expected-error{{an attribute list cannot appear here}}
2012-06-23 13:07:58 +08:00
[ [ ] ] friend int h ( ) {
}
2012-11-29 07:17:40 +08:00
[ [ ] ] friend int f3 ( ) , f4 ( ) , f5 ( ) ; // expected-error{{an attribute list cannot appear here}}
friend int f6 [[noreturn]] (), f7 [[noreturn]] (), f8 [[noreturn]] ( ) ; // expected-error3 {{an attribute list cannot appear here}}
2012-06-23 13:07:58 +08:00
friend class [ [ ] ] C ; // expected-error{{an attribute list cannot appear here}}
2012-11-29 07:17:40 +08:00
[ [ ] ] friend class D ; // expected-error{{an attribute list cannot appear here}}
[ [ ] ] friend int ; // expected-error{{an attribute list cannot appear here}}
2012-06-23 13:07:58 +08:00
} ;
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 ) ;
2009-11-21 16:43:09 +08:00
// Argument tests
2011-09-30 02:04:28 +08:00
alignas int aligned_no_params ; // expected-error {{expected '('}}
2012-02-04 17:53:13 +08:00
alignas ( i ) int aligned_nonconst ; // expected-error {{'aligned' attribute requires integer constant}} expected-note {{read of non-const variable 'i'}}
2009-11-21 16:43:09 +08:00
// Statement tests
void foo ( ) {
[ [ ] ] ;
[ [ ] ] { }
[ [ ] ] if ( 0 ) { }
[ [ ] ] for ( ; ; ) ;
[ [ ] ] do {
[ [ ] ] continue ;
} while ( 0 ) ;
[ [ ] ] while ( 0 ) ;
2013-11-28 02:53:58 +08:00
2009-11-21 16:43:09 +08:00
[ [ ] ] switch ( i ) {
[ [ ] ] case 0 :
[ [ ] ] default :
[ [ ] ] break ;
}
2013-11-28 02:53:58 +08:00
2009-11-21 16:43:09 +08:00
[ [ ] ] goto there ;
[ [ ] ] there :
2013-11-28 02:53:58 +08:00
2009-11-21 16:43:09 +08:00
[ [ ] ] try {
} [ [ ] ] catch ( . . . ) { // expected-error {{an attribute list cannot appear here}}
}
2012-04-10 09:32:12 +08:00
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}}
2012-04-11 12:01:28 +08:00
void bar [[noreturn]] ([[]] int i, [[]] int j ) ;
using FuncType = void ( [ [ ] ] int ) ;
void baz ( [ [ ] ] . . . ) ; // expected-error {{expected parameter declarator}}
2009-11-21 16:43:09 +08:00
[ [ ] ] return ;
}
2012-04-10 11:25:07 +08:00
template < typename . . . Ts > void variadic ( ) {
void bar [[noreturn...]] ( ) ; // expected-error {{attribute 'noreturn' cannot be used as an attribute pack}}
}
2012-06-23 13:07:58 +08:00
// Expression tests
void bar ( ) {
2013-01-17 09:30:42 +08:00
// FIXME: GCC accepts [[gnu::noreturn]] on a lambda, even though it appertains
// to the operator()'s type, and GCC does not otherwise accept attributes
// applied to types. Use that to test this.
[ ] ( ) [[gnu::noreturn]] { return ; } ( ) ; // expected-warning {{attribute 'noreturn' ignored}} FIXME-error {{should not return}}
[ ] ( ) [[gnu::noreturn]] { throw ; } ( ) ; // expected-warning {{attribute 'noreturn' ignored}}
2012-06-23 13:07:58 +08:00
new int [ 42 ] [[]][5][[]] { } ;
}
// Condition tests
void baz ( ) {
2013-02-21 03:22:51 +08:00
if ( [[unknown]] bool b = true ) { // expected-warning {{unknown attribute 'unknown' ignored}}
switch ( [[unknown]] int n { 42 } ) { // expected-warning {{unknown attribute 'unknown' ignored}}
2012-06-23 13:07:58 +08:00
default :
2013-02-21 03:22:51 +08:00
for ( [[unknown]] int n = 0; [[unknown]] char b = n < 5 ; + + b ) { // expected-warning 2{{unknown attribute 'unknown' ignored}}
2012-06-23 13:07:58 +08:00
}
}
}
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}}
2013-02-21 03:22:51 +08:00
for ( [[unknown]] int n : { 1 , 2 , 3 } ) { // expected-warning {{unknown attribute 'unknown' ignored}}
2012-06-23 13:07:58 +08:00
}
}
2012-06-24 06:30:04 +08:00
enum class __attribute__ ( ( visibility ( " hidden " ) ) ) SecretKeepers {
one , /* rest are deprecated */ two , three
} ;
enum class [ [ ] ] EvenMoreSecrets { } ;
2012-10-03 09:56:22 +08:00
namespace arguments {
2013-01-14 15:53:01 +08:00
void f [[gnu::format(printf, 1, 2)]] ( const char * , . . . ) ;
2014-04-01 01:32:39 +08:00
void g ( ) [[unknown::foo(ignore arguments for unknown attributes, even with symbols!)]] ; // expected-warning {{unknown attribute 'foo' ignored}}
[[deprecated("with argument")]] int i ;
2015-02-17 07:12:37 +08:00
// expected-warning@-1 {{use of the 'deprecated' attribute is a C++14 extension}}
2012-10-03 09:56:22 +08:00
}
2012-11-07 03:34:54 +08:00
2013-01-14 15:53:01 +08:00
// Forbid attributes on decl specifiers.
2013-01-29 18:02:16 +08:00
unsigned [[gnu::used]] static int [[gnu::unused]] v1 ; / / expected - error { { ' unused ' attribute cannot be applied to types } } \
2012-11-07 03:34:54 +08:00
expected - error { { an attribute list cannot appear here } }
2013-01-29 18:02:16 +08:00
typedef [[gnu::used]] unsigned long [[gnu::unused]] v2 ; / / expected - error { { ' unused ' attribute cannot be applied to types } } \
2012-11-07 03:34:54 +08:00
expected - error { { an attribute list cannot appear here } }
2013-01-29 18:02:16 +08:00
int [[carries_dependency]] foo(int [[carries_dependency]] x ) ; // expected-error 2{{'carries_dependency' attribute cannot be applied to types}}
2013-01-14 15:53:01 +08:00
// Forbid [[gnu::...]] attributes on declarator chunks.
int * [[gnu::unused]] v3 ; // expected-warning {{attribute 'unused' ignored}}
int v4 [ 2 ] [[gnu::unused]] ; // expected-warning {{attribute 'unused' ignored}}
int v5 ( ) [[gnu::unused]] ; // expected-warning {{attribute 'unused' ignored}}
2013-02-21 03:22:51 +08:00
[[attribute_declaration]] ; // expected-warning {{unknown attribute 'attribute_declaration' ignored}}
2013-11-28 02:53:58 +08:00
[[noreturn]] ; // expected-error {{'noreturn' attribute only applies to functions}}
2013-02-23 01:15:32 +08:00
[[carries_dependency]] ; // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
2013-09-06 08:12:20 +08:00
class A {
A ( [[gnu::unused]] int a ) ;
} ;
A : : A ( [[gnu::unused]] int a ) { }
2013-10-29 11:33:57 +08:00
namespace GccConst {
// GCC's tokenizer treats const and __const as the same token.
[[gnu::const]] int * f1 ( ) ;
[[gnu::__const]] int * f2 ( ) ;
2013-12-01 05:17:12 +08:00
[[gnu::__const__]] int * f3 ( ) ;
2013-10-29 11:33:57 +08:00
void f ( const int * ) ;
void g ( ) { f ( f1 ( ) ) ; f ( f2 ( ) ) ; }
2013-12-01 05:17:12 +08:00
void h ( ) { f ( f3 ( ) ) ; }
2013-10-29 11:33:57 +08:00
}
2013-10-29 11:54:41 +08:00
namespace GccASan {
__attribute__ ( ( no_address_safety_analysis ) ) void f1 ( ) ;
__attribute__ ( ( no_sanitize_address ) ) void f2 ( ) ;
[[gnu::no_address_safety_analysis]] void f3 ( ) ;
[[gnu::no_sanitize_address]] void f4 ( ) ;
}
2014-04-15 00:03:22 +08:00
namespace {
[[deprecated]] void bar ( ) ;
2015-02-17 07:12:37 +08:00
// expected-warning@-1 {{use of the 'deprecated' attribute is a C++14 extension}}
2014-04-15 00:03:22 +08:00
[[deprecated("hello")]] void baz ( ) ;
2015-02-17 07:12:37 +08:00
// expected-warning@-1 {{use of the 'deprecated' attribute is a C++14 extension}}
2015-02-17 06:27:01 +08:00
[[deprecated()]] void foo ( ) ;
// expected-error@-1 {{parentheses must be omitted if 'deprecated' attribute's argument list is empty}}
2014-04-15 00:03:22 +08:00
[[gnu::deprecated()]] void quux ( ) ;
}
2015-01-10 02:09:39 +08:00
namespace {
[ [ // expected-error {{expected ']'}}
# pragma pack(pop)
deprecated
] ] void bad ( ) ;
}
2015-03-30 03:25:07 +08:00
2016-03-08 08:32:55 +08:00
int fallthru ( int n ) {
switch ( n ) {
case 0 :
n + = 5 ;
[[fallthrough]] ; // expected-warning {{use of the 'fallthrough' attribute is a C++1z extension}}
case 1 :
n * = 2 ;
break ;
}
return n ;
}
2015-03-30 03:25:07 +08:00
# define attr_name bitand
# define attr_name_2(x) x
# define attr_name_3(x, y) x##y
[[attr_name, attr_name_2(bitor), attr_name_3(com, pl)]] int macro_attrs ; / / expected - warning { { unknown attribute ' compl ' ignored } } \
expected - warning { { unknown attribute ' bitor ' ignored } } \
expected - warning { { unknown attribute ' bitand ' ignored } }