xref: /llvm-project/clang/test/Sema/code_align.c (revision 324436c29ffd14bcf96c94500d5e43391f2b1e51)
1 // RUN: %clang_cc1 -triple x86_64-pc-linux -fsyntax-only -verify=expected,c-local -x c %s
2 // RUN: %clang_cc1 -triple x86_64-pc-linux -fsyntax-only -verify=expected,cpp-local -pedantic -x c++ -std=c++11 %s
3 
foo()4 void foo() {
5   int i;
6   int a[10], b[10];
7 
8   [[clang::code_align(8)]]
9   for (i = 0; i < 10; ++i) {  // this is OK
10     a[i] = b[i] = 0;
11   }
12   // expected-error@+1{{'code_align' attribute only applies to 'for', 'while', and 'do' statements}}
13   [[clang::code_align(4)]]
14   i = 7;
15   for (i = 0; i < 10; ++i) {
16     a[i] = b[i] = 0;
17   }
18 
19   // expected-error@+1{{'code_align' attribute cannot be applied to a declaration}}
20   [[clang::code_align(12)]] int n[10];
21 }
22 
23 void bar(int);
24 // cpp-local-note@+1{{declared here}}
foo1(int A)25 void foo1(int A)
26 {
27   // expected-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; provided argument was 0}}
28   [[clang::code_align(0)]]
29   for(int I=0; I<128; ++I) { bar(I); }
30 
31   // expected-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; provided argument was -4}}
32   [[clang::code_align(-4)]]
33   for(int I=0; I<128; ++I) { bar(I); }
34 
35     // cpp-local-error@+2{{integral constant expression must have integral or unscoped enumeration type, not 'double'}}
36     // c-local-error@+1{{integer constant expression must have integer type, not 'double'}}
37   [[clang::code_align(64.0)]]
38   for(int I=0; I<128; ++I) { bar(I); }
39 
40   // expected-error@+1{{'code_align' attribute takes one argument}}
41   [[clang::code_align()]]
42   for(int I=0; I<128; ++I) { bar(I); }
43 
44   // expected-error@+1{{'code_align' attribute takes one argument}}
45   [[clang::code_align(4,8)]]
46   for(int I=0; I<128; ++I) { bar(I); }
47 
48   // no diagnostic is expected
49   [[clang::code_align(32)]]
50   for(int I=0; I<128; ++I) { bar(I); }
51 
52   // cpp-local-error@+2{{integral constant expression must have integral or unscoped enumeration type, not 'const char[4]'}}
53   // c-local-error@+1{{integer constant expression must have integer type, not 'char[4]'}}
54   [[clang::code_align("abc")]]
55   for(int I=0; I<128; ++I) { bar(I); }
56 
57   [[clang::code_align(64)]] // OK
58   [[clang::code_align(64)]] // OK
59   for(int I=0; I<128; ++I) { bar(I); }
60 
61   [[clang::code_align(8)]]  // expected-note{{previous attribute is here}}
62   [[clang::code_align(64)]] // expected-error{{conflicting loop attribute 'code_align'}}
63   for(int I=0; I<128; ++I) { bar(I); }
64 
65   [[clang::code_align(4)]] // expected-note{{previous attribute is here}}
66   [[clang::code_align(4)]] // OK
67   [[clang::code_align(8)]] // expected-error{{conflicting loop attribute 'code_align'}}
68   for(int I=0; I<128; ++I) { bar(I); }
69 
70   [[clang::code_align(4)]]  // expected-note 2{{previous attribute is here}}
71   [[clang::code_align(4)]]  // OK
72   [[clang::code_align(8)]]  // expected-error{{conflicting loop attribute 'code_align'}}
73   [[clang::code_align(64)]] // expected-error{{conflicting loop attribute 'code_align'}}
74   for(int I=0; I<128; ++I) { bar(I); }
75 
76   // expected-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; provided argument was 7}}
77   [[clang::code_align(7)]]
78   for(int I=0; I<128; ++I) { bar(I); }
79 
80   // expected-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; provided argument was 5000}}
81   [[clang::code_align(5000)]]
82   for(int I=0; I<128; ++I) { bar(I); }
83 
84   // expected-warning@+2{{integer literal is too large to be represented in a signed integer type, interpreting as unsigned}}
85   // expected-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; provided argument was -9223372036854775808}}
86   [[clang::code_align(9223372036854775808)]]
87   for(int I=0; I<256; ++I) { bar(I); }
88 
89 #ifdef __SIZEOF_INT128__
90   // expected-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; provided argument was (__int128_t)1311768467294899680ULL << 64}}
91   [[clang::code_align((__int128_t)0x1234567890abcde0ULL << 64)]]
92   for(int I=0; I<256; ++I) { bar(I); }
93 #endif
94 
95   // expected-error@+1 {{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; provided argument was -922337203685477}}
96   [[clang::code_align(-922337203685477)]]
97   for(int I=0; I<256; ++I) { bar(I); }
98 
99 #ifdef __SIZEOF_INT128__
100   // cpp-local-error@+3{{expression is not an integral constant expression}}
101   // cpp-local-note@+2{{left shift of negative value -1311768467294899680}}
102   // c-local-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; provided argument was -(__int128_t)1311768467294899680ULL << 64}}
103   [[clang::code_align(-(__int128_t)0x1234567890abcde0ULL << 64)]]
104   for(int I=0; I<256; ++I) { bar(I); }
105 #endif
106 
107   // cpp-local-error@+3{{expression is not an integral constant expression}}
108   // cpp-local-note@+2{{function parameter 'A' with unknown value cannot be used in a constant expression}}
109   // c-local-error@+1{{expression is not an integer constant expression}}
110   [[clang::code_align(A)]]
111   for(int I=0; I<128; ++I) { bar(I); }
112 }
113 
check_code_align_expression()114 void check_code_align_expression() {
115   int a[10];
116 
117   // Test that checks expression is not a constant expression.
118   int foo2; // cpp-local-note {{declared here}}
119   // c-local-error@+3{{expression is not an integer constant expression}}
120   // cpp-local-error@+2{{expression is not an integral constant expression}}
121   // cpp-local-note@+1{{read of non-const variable 'foo2' is not allowed in a constant expression}}
122   [[clang::code_align(foo2 + 1)]]
123   for (int i = 0; i != 10; ++i)
124     a[i] = 0;
125 
126 #if __cplusplus >= 201103L
127   // Test that checks expression is a constant expression.
128   constexpr int bars = 0;
129   [[clang::code_align(bars + 1)]]
130   for (int i = 0; i != 10; ++i)
131     a[i] = 0;
132 #endif
133 }
134 
135 #if __cplusplus >= 201103L
136 template <int A, int B, int C, int D, int E>
code_align_dependent()137 void code_align_dependent() {
138   [[clang::code_align(C)]]
139   for(int I=0; I<128; ++I) { bar(I); }
140 
141   [[clang::code_align(A)]] // OK
142   [[clang::code_align(A)]] // OK
143   for(int I=0; I<128; ++I) { bar(I); }
144 
145   [[clang::code_align(A)]] // cpp-local-note{{previous attribute is here}}
146   [[clang::code_align(E)]] // cpp-local-error{{conflicting loop attribute 'code_align'}}
147   for(int I=0; I<128; ++I) { bar(I); }
148 
149   [[clang::code_align(A)]] // cpp-local-note{{previous attribute is here}}
150   [[clang::code_align(A)]] // OK
151   [[clang::code_align(E)]] // cpp-local-error{{conflicting loop attribute 'code_align'}}
152   for(int I=0; I<128; ++I) { bar(I); }
153 
154   [[clang::code_align(A)]] // cpp-local-note 2{{previous attribute is here}}
155   [[clang::code_align(A)]] // OK
156   [[clang::code_align(C)]] // cpp-local-error{{conflicting loop attribute 'code_align'}}
157   [[clang::code_align(E)]] // cpp-local-error{{conflicting loop attribute 'code_align'}}
158   for(int I=0; I<128; ++I) { bar(I); }
159 
160   // cpp-local-error@+1{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; provided argument was 23}}
161   [[clang::code_align(B)]]
162   for(int I=0; I<128; ++I) { bar(I); }
163 
164   // cpp-local-error@+2{{'code_align' attribute requires an integer argument which is a constant power of two between 1 and 4096 inclusive; provided argument was -10}}
165   // cpp-local-note@#neg-instantiation{{in instantiation of function template specialization 'code_align_dependent<8, 23, 32, -10, 64>' requested here}}
166   [[clang::code_align(D)]]
167   for(int I=0; I<128; ++I) { bar(I); }
168 }
169 
170 template<int ITMPL>
bar3()171 void bar3() {
172   [[clang::code_align(8)]]      // cpp-local-note{{previous attribute is here}}
173   [[clang::code_align(ITMPL)]] // cpp-local-error{{conflicting loop attribute 'code_align'}} \
174 	                       // cpp-local-note@#temp-instantiation{{in instantiation of function template specialization 'bar3<4>' requested here}}
175   for(int I=0; I<128; ++I) { bar(I); }
176 }
177 
178 template<int ITMPL1>
bar4()179 void bar4() {
180   [[clang::code_align(ITMPL1)]] // cpp-local-note{{previous attribute is here}}
181   [[clang::code_align(32)]]    // cpp-local-error{{conflicting loop attribute 'code_align'}} \
182 	                       // cpp-local-note@#temp-instantiation1{{in instantiation of function template specialization 'bar4<64>' requested here}}
183   for(int I=0; I<128; ++I) { bar(I); }
184 }
185 
main()186 int main() {
187   code_align_dependent<8, 23, 32, -10, 64>(); // #neg-instantiation
188   bar3<4>();  // #temp-instantiation
189   bar4<64>(); // #temp-instantiation1
190   return 0;
191 }
192 #endif
193