summaryrefslogtreecommitdiffstats
path: root/test/Frontend/fixed_point_errors.c
blob: db15bd874b316992f087b2cf4f2bc7afaadc4362 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
// RUN: %clang_cc1 -verify -ffixed-point %s

/* We do not yet support long long. No recommended bit widths are given for this
 * size. */

long long _Accum longlong_accum;              // expected-error{{'long long _Accum' is invalid}}
unsigned long long _Accum u_longlong_accum;   // expected-error{{'long long _Accum' is invalid}}
long long _Fract longlong_fract;              // expected-error{{'long long _Fract' is invalid}}
unsigned long long _Fract u_longlong_fract;   // expected-error{{'long long _Fract' is invalid}}

_Sat long long _Accum sat_longlong_accum;             // expected-error{{'long long _Accum' is invalid}}
_Sat unsigned long long _Accum sat_u_longlong_accum;  // expected-error{{'long long _Accum' is invalid}}
_Sat long long _Fract sat_longlong_fract;             // expected-error{{'long long _Fract' is invalid}}
_Sat unsigned long long _Fract sat_u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}


/* Although _Complex types work with floating point numbers, the extension
 * provides no info for complex fixed point types. */

_Complex signed short _Accum cmplx_s_short_accum;   // expected-error{{'_Complex _Accum' is invalid}}
_Complex signed _Accum cmplx_s_accum;               // expected-error{{'_Complex _Accum' is invalid}}
_Complex signed long _Accum cmplx_s_long_accum;     // expected-error{{'_Complex _Accum' is invalid}}
_Complex unsigned short _Accum cmplx_u_short_accum; // expected-error{{'_Complex _Accum' is invalid}}
_Complex unsigned _Accum cmplx_u_accum;             // expected-error{{'_Complex _Accum' is invalid}}
_Complex unsigned long _Accum cmplx_u_long_accum;   // expected-error{{'_Complex _Accum' is invalid}}
_Complex short _Accum cmplx_s_short_accum;          // expected-error{{'_Complex _Accum' is invalid}}
_Complex _Accum cmplx_s_accum;                      // expected-error{{'_Complex _Accum' is invalid}}
_Complex long _Accum cmplx_s_long_accum;            // expected-error{{'_Complex _Accum' is invalid}}

_Complex signed short _Fract cmplx_s_short_fract;   // expected-error{{'_Complex _Fract' is invalid}}
_Complex signed _Fract cmplx_s_fract;               // expected-error{{'_Complex _Fract' is invalid}}
_Complex signed long _Fract cmplx_s_long_fract;     // expected-error{{'_Complex _Fract' is invalid}}
_Complex unsigned short _Fract cmplx_u_short_fract; // expected-error{{'_Complex _Fract' is invalid}}
_Complex unsigned _Fract cmplx_u_fract;             // expected-error{{'_Complex _Fract' is invalid}}
_Complex unsigned long _Fract cmplx_u_long_fract;   // expected-error{{'_Complex _Fract' is invalid}}
_Complex short _Fract cmplx_s_short_fract;          // expected-error{{'_Complex _Fract' is invalid}}
_Complex _Fract cmplx_s_fract;                      // expected-error{{'_Complex _Fract' is invalid}}
_Complex long _Fract cmplx_s_long_fract;            // expected-error{{'_Complex _Fract' is invalid}}

_Complex _Sat signed short _Accum cmplx_sat_s_short_accum;   // expected-error{{'_Complex _Accum' is invalid}}
_Complex _Sat signed _Accum cmplx_sat_s_accum;               // expected-error{{'_Complex _Accum' is invalid}}
_Complex _Sat signed long _Accum cmplx_sat_s_long_accum;     // expected-error{{'_Complex _Accum' is invalid}}
_Complex _Sat unsigned short _Accum cmplx_sat_u_short_accum; // expected-error{{'_Complex _Accum' is invalid}}
_Complex _Sat unsigned _Accum cmplx_sat_u_accum;             // expected-error{{'_Complex _Accum' is invalid}}
_Complex _Sat unsigned long _Accum cmplx_sat_u_long_accum;   // expected-error{{'_Complex _Accum' is invalid}}
_Complex _Sat short _Accum cmplx_sat_s_short_accum;          // expected-error{{'_Complex _Accum' is invalid}}
_Complex _Sat _Accum cmplx_sat_s_accum;                      // expected-error{{'_Complex _Accum' is invalid}}
_Complex _Sat long _Accum cmplx_sat_s_long_accum;            // expected-error{{'_Complex _Accum' is invalid}}

_Complex signed short _Fract cmplx_sat_s_short_fract;   // expected-error{{'_Complex _Fract' is invalid}}
_Complex signed _Fract cmplx_sat_s_fract;               // expected-error{{'_Complex _Fract' is invalid}}
_Complex signed long _Fract cmplx_sat_s_long_fract;     // expected-error{{'_Complex _Fract' is invalid}}
_Complex unsigned short _Fract cmplx_sat_u_short_fract; // expected-error{{'_Complex _Fract' is invalid}}
_Complex unsigned _Fract cmplx_sat_u_fract;             // expected-error{{'_Complex _Fract' is invalid}}
_Complex unsigned long _Fract cmplx_sat_u_long_fract;   // expected-error{{'_Complex _Fract' is invalid}}
_Complex short _Fract cmplx_sat_s_short_fract;          // expected-error{{'_Complex _Fract' is invalid}}
_Complex _Fract cmplx_sat_s_fract;                      // expected-error{{'_Complex _Fract' is invalid}}
_Complex long _Fract cmplx_sat_s_long_fract;            // expected-error{{'_Complex _Fract' is invalid}}

/* Bad combinations */
float _Accum f_accum;     // expected-error{{cannot combine with previous 'float' declaration specifier}}
double _Accum d_accum;    // expected-error{{cannot combine with previous 'double' declaration specifier}}
_Bool _Accum b_accum;     // expected-error{{cannot combine with previous '_Bool' declaration specifier}}
char _Accum c_accum;      // expected-error{{cannot combine with previous 'char' declaration specifier}}
int _Accum i_accum;       // expected-error{{cannot combine with previous 'int' declaration specifier}}

float _Fract f_fract;     // expected-error{{cannot combine with previous 'float' declaration specifier}}
double _Fract d_fract;    // expected-error{{cannot combine with previous 'double' declaration specifier}}
_Bool _Fract b_fract;     // expected-error{{cannot combine with previous '_Bool' declaration specifier}}
char _Fract c_fract;      // expected-error{{cannot combine with previous 'char' declaration specifier}}
int _Fract i_fract;       // expected-error{{cannot combine with previous 'int' declaration specifier}}

/* Bad saturated combinations */
_Sat float f;             // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'float'}}
_Sat double d;            // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'double'}}
_Sat _Bool b;             // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not '_Bool'}}
_Sat char c;              // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'char'}}
_Sat int i;               // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'int'}}
_Sat _Sat _Fract fract;   // expected-warning{{duplicate '_Sat' declaration specifier}}


/* Literals that cannot fit into types */
signed short _Accum s_short_accum = 256.0hk;            // expected-error{{this value is too large for this fixed point type}}
unsigned short _Accum u_short_accum = 256.0uhk;         // expected-error{{this value is too large for this fixed point type}}
signed _Accum s_accum = 65536.0k;                       // expected-error{{this value is too large for this fixed point type}}
unsigned _Accum u_accum = 65536.0uk;                    // expected-error{{this value is too large for this fixed point type}}
signed long _Accum s_long_accum = 4294967296.0lk;       // expected-error{{this value is too large for this fixed point type}}
unsigned long _Accum u_long_accum = 4294967296.0ulk;    // expected-error{{this value is too large for this fixed point type}}

// Large values from decimal exponents
short _Accum          short_accum_exp   = 2.56e2hk;           // expected-error{{this value is too large for this fixed point type}}
_Accum                accum_exp         = 6.5536e4k;          // expected-error{{this value is too large for this fixed point type}}
long _Accum           long_accum_exp    = 4.294967296e9lk;    // expected-error{{this value is too large for this fixed point type}}
unsigned short _Accum u_short_accum_exp = 2.56e2uhk;          // expected-error{{this value is too large for this fixed point type}}
unsigned _Accum       u_accum_exp       = 6.5536e4uk;         // expected-error{{this value is too large for this fixed point type}}
unsigned long _Accum  u_long_accum_exp  = 4.294967296e9ulk;   // expected-error{{this value is too large for this fixed point type}}

// Large value from hexidecimal exponents
short _Accum          short_accum_hex_exp   = 0x1p8hk;        // expected-error{{this value is too large for this fixed point type}}
_Accum                accum_hex_exp         = 0x1p16k;        // expected-error{{this value is too large for this fixed point type}}
long _Accum           long_accum_hex_exp    = 0x1p32lk;       // expected-error{{this value is too large for this fixed point type}}
unsigned short _Accum u_short_accum_hex_exp = 0x1p8uhk;       // expected-error{{this value is too large for this fixed point type}}
unsigned _Accum       u_accum_hex_exp       = 0x1p16uk;       // expected-error{{this value is too large for this fixed point type}}
unsigned long _Accum  u_long_accum_hex_exp  = 0x1p32ulk;      // expected-error{{this value is too large for this fixed point type}}

// Very large exponent
_Accum x = 1e1000000000000000000000000000000000k;   // expected-error{{this value is too large for this fixed point type}}

/* Although _Fract's cannot equal 1, _Fract literals written as 1 are allowed
 * and the underlying value represents the max value for that _Fract type. */
short _Fract          short_fract_above_1    = 1.1hr;   // expected-error{{this value is too large for this fixed point type}}
_Fract                fract_above_1          = 1.1r;    // expected-error{{this value is too large for this fixed point type}}
long _Fract           long_fract_above_1     = 1.1lr;   // expected-error{{this value is too large for this fixed point type}}
unsigned short _Fract u_short_fract_above_1  = 1.1uhr;  // expected-error{{this value is too large for this fixed point type}}
unsigned _Fract       u_fract_above_1        = 1.1ur;   // expected-error{{this value is too large for this fixed point type}}
unsigned long _Fract  u_long_fract_above_1   = 1.1ulr;  // expected-error{{this value is too large for this fixed point type}}

short _Fract          short_fract_hex_exp   = 0x0.fp1hr;      // expected-error{{this value is too large for this fixed point type}}
_Fract                fract_hex_exp         = 0x0.fp1r;       // expected-error{{this value is too large for this fixed point type}}
long _Fract           long_fract_hex_exp    = 0x0.fp1lr;      // expected-error{{this value is too large for this fixed point type}}
unsigned short _Fract u_short_fract_hex_exp = 0x0.fp1uhr;     // expected-error{{this value is too large for this fixed point type}}
unsigned _Fract       u_fract_hex_exp       = 0x0.fp1ur;      // expected-error{{this value is too large for this fixed point type}}
unsigned long _Fract  u_long_fract_hex_exp  = 0x0.fp1ulr;     // expected-error{{this value is too large for this fixed point type}}

/* Do not allow typedef to be used with typedef'd types */
typedef short _Fract shortfract_t;
typedef short _Accum shortaccum_t;
typedef _Fract fract_t;
typedef _Accum accum_t;
typedef long _Fract longfract_t;
typedef long _Accum longaccum_t;
_Sat shortfract_t td_sat_short_fract;       // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}
_Sat shortaccum_t td_sat_short_accum;       // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}
_Sat fract_t td_sat_fract;                  // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}
_Sat accum_t td_sat_accum;                  // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}
_Sat longfract_t td_sat_long_fract;         // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}
_Sat longaccum_t td_sat_long_accum;         // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}

/* Bad suffixes  */
_Accum fk = 1.0fk;    // expected-error{{invalid suffix 'fk' on integer constant}}
_Accum kk = 1.0kk;    // expected-error{{invalid suffix 'kk' on integer constant}}
_Accum rk = 1.0rk;    // expected-error{{invalid suffix 'rk' on integer constant}}
_Accum rk = 1.0rr;    // expected-error{{invalid suffix 'rr' on integer constant}}
_Accum qk = 1.0qr;    // expected-error{{invalid suffix 'qr' on integer constant}}

/* Using wrong exponent notation */
_Accum dec_with_hex_exp1 = 0.1p10k;    // expected-error{{invalid suffix 'p10k' on integer constant}}
_Accum dec_with_hex_exp2 = 0.1P10k;    // expected-error{{invalid suffix 'P10k' on integer constant}}
_Accum hex_with_dex_exp1 = 0x0.1e10k;  // expected-error{{hexadecimal floating constant requires an exponent}}
_Accum hex_with_dex_exp2 = 0x0.1E10k;  // expected-error{{hexadecimal floating constant requires an exponent}}

void CheckSuffixOnIntegerLiterals() {
  _Accum short_acc_int;
  _Accum acc_int;
  _Accum long_acc_int;

  _Accum u_short_acc_int;
  _Accum u_acc_int;
  _Accum u_long_acc_int;

  _Fract short_fract_int;
  _Fract fract_int;
  _Fract long_fract_int;

  _Fract u_short_fract_int;
  _Fract u_fract_int;
  _Fract u_long_fract_int;

  // Decimal integer literals (non-zero)
  short_acc_int = 10hk; // expected-error{{invalid suffix 'hk' on integer constant}}
  acc_int = 10k;        // expected-error{{invalid suffix 'k' on integer constant}}
  long_acc_int = 10lk;  // expected-error{{invalid suffix 'lk' on integer constant}}

  u_short_acc_int = 10uhk; // expected-error{{invalid suffix 'uhk' on integer constant}}
  u_acc_int = 10uk;        // expected-error{{invalid suffix 'uk' on integer constant}}
  u_long_acc_int = 10ulk;  // expected-error{{invalid suffix 'ulk' on integer constant}}

  short_fract_int = 10hr; // expected-error{{invalid suffix 'hr' on integer constant}}
  fract_int = 10r;        // expected-error{{invalid suffix 'r' on integer constant}}
  long_fract_int = 10lr;  // expected-error{{invalid suffix 'lr' on integer constant}}

  u_short_fract_int = 10uhr; // expected-error{{invalid suffix 'uhr' on integer constant}}
  u_fract_int = 10ur;        // expected-error{{invalid suffix 'ur' on integer constant}}
  u_long_fract_int = 10ulr;  // expected-error{{invalid suffix 'ulr' on integer constant}}

  // Decimal integer literals (0)
  short_acc_int = 0hk; // expected-error{{invalid suffix 'hk' on integer constant}}
  acc_int = 0k;        // expected-error{{invalid suffix 'k' on integer constant}}
  long_acc_int = 0lk;  // expected-error{{invalid suffix 'lk' on integer constant}}

  // Decimal integer literals (large number)
  acc_int = 999999999999999999k;   // expected-error{{invalid suffix 'k' on integer constant}}
  fract_int = 999999999999999999r; // expected-error{{invalid suffix 'r' on integer constant}}

  // Octal integer literals
  short_acc_int = 010hk; // expected-error{{invalid suffix 'hk' on integer constant}}
  acc_int = 010k;        // expected-error{{invalid suffix 'k' on integer constant}}
  long_acc_int = 010lk;  // expected-error{{invalid suffix 'lk' on integer constant}}

  u_short_acc_int = 010uhk; // expected-error{{invalid suffix 'uhk' on integer constant}}
  u_acc_int = 010uk;        // expected-error{{invalid suffix 'uk' on integer constant}}
  u_long_acc_int = 010ulk;  // expected-error{{invalid suffix 'ulk' on integer constant}}

  short_fract_int = 010hr; // expected-error{{invalid suffix 'hr' on integer constant}}
  fract_int = 010r;        // expected-error{{invalid suffix 'r' on integer constant}}
  long_fract_int = 010lr;  // expected-error{{invalid suffix 'lr' on integer constant}}

  u_short_fract_int = 010uhr; // expected-error{{invalid suffix 'uhr' on integer constant}}
  u_fract_int = 010ur;        // expected-error{{invalid suffix 'ur' on integer constant}}
  u_long_fract_int = 010ulr;  // expected-error{{invalid suffix 'ulr' on integer constant}}

  // Hexadecimal integer literals
  short_acc_int = 0x10hk; // expected-error{{invalid suffix 'hk' on integer constant}}
  acc_int = 0x10k;        // expected-error{{invalid suffix 'k' on integer constant}}
  long_acc_int = 0x10lk;  // expected-error{{invalid suffix 'lk' on integer constant}}

  u_short_acc_int = 0x10uhk; // expected-error{{invalid suffix 'uhk' on integer constant}}
  u_acc_int = 0x10uk;        // expected-error{{invalid suffix 'uk' on integer constant}}
  u_long_acc_int = 0x10ulk;  // expected-error{{invalid suffix 'ulk' on integer constant}}

  short_fract_int = 0x10hr; // expected-error{{invalid suffix 'hr' on integer constant}}
  fract_int = 0x10r;        // expected-error{{invalid suffix 'r' on integer constant}}
  long_fract_int = 0x10lr;  // expected-error{{invalid suffix 'lr' on integer constant}}

  u_short_fract_int = 0x10uhr; // expected-error{{invalid suffix 'uhr' on integer constant}}
  u_fract_int = 0x10ur;        // expected-error{{invalid suffix 'ur' on integer constant}}
  u_long_fract_int = 0x10ulr;  // expected-error{{invalid suffix 'ulr' on integer constant}}

  // Using auto
  auto auto_fract = 0r;  // expected-error{{invalid suffix 'r' on integer constant}}
                         // expected-warning@-1{{type specifier missing, defaults to 'int'}}
  auto auto_accum = 0k;  // expected-error{{invalid suffix 'k' on integer constant}}
                         // expected-warning@-1{{type specifier missing, defaults to 'int'}}
}

// Ok conversions
int i_const = -2.5hk;
_Sat short _Accum sat_sa_const2 = 256.0k;
_Sat unsigned short _Accum sat_usa_const = -1.0hk;
short _Accum sa_const3 = 2;
short _Accum sa_const4 = -2;

// Overflow
short _Accum sa_const = 256.0k;   // expected-warning{{implicit conversion from 256.0 cannot fit within the range of values for 'short _Accum'}}
short _Fract sf_const = 1.0hk;    // expected-warning{{implicit conversion from 1.0 cannot fit within the range of values for 'short _Fract'}}
unsigned _Accum ua_const = -1.0k; // expected-warning{{implicit conversion from -1.0 cannot fit within the range of values for 'unsigned _Accum'}}
short _Accum sa_const2 = 128.0k + 128.0k; // expected-warning{{implicit conversion from 256.0 cannot fit within the range of values for 'short _Accum'}}
short s_const = 65536.0lk;                // expected-warning{{implicit conversion from 65536.0 cannot fit within the range of values for 'short'}}
unsigned u_const = -2.5hk;                // expected-warning{{implicit conversion from -2.5 cannot fit within the range of values for 'unsigned int'}}
char c_const = 256.0uk;                   // expected-warning{{implicit conversion from 256.0 cannot fit within the range of values for 'char'}}
short _Accum sa_const5 = 256;             // expected-warning{{implicit conversion from 256 cannot fit within the range of values for 'short _Accum'}}
unsigned short _Accum usa_const2 = -2;    // expected-warning{{implicit conversion from -2 cannot fit within the range of values for 'unsigned short _Accum'}}