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