1// -Wall
2#pragma version(1)
3#pragma rs java_package_name(fn)
4
5// Various ways particular reduction consituent functions can fail semantic checks.
6// Also see reduce_general_bad_halter.rs for halter function semantic checks.
7// Also see reduce_general_bad_accumulator.rs for accumulator data type checks.
8
9// trivial accumulator for use multiple times later
10static void AccumInt(int *accum, int val) { }
11
12/////////////////////////////////////////////////////////////////////////////
13// initializer
14/////////////////////////////////////////////////////////////////////////////
15
16// initializer must take exactly 1 parameter
17#pragma rs reduce(init0) initializer(init0) accumulator(AccumInt)
18static void init0() { }
19
20// initializer must take exactly 1 parameter
21#pragma rs reduce(init2) initializer(init2) accumulator(AccumInt)
22static void init2(int *a, int *b) { }
23
24// initializer cannot take special parameter
25#pragma rs reduce(init_special1) initializer(init_special1) accumulator(AccumInt)
26static void init_special1(int *x) { }
27
28// initializer must take exactly 1 parameter
29#pragma rs reduce(init2_special1) initializer(init2_special1) accumulator(AccumInt)
30static void init2_special1(int *a, int *x) { }
31
32// initializer must take exactly 1 parameter
33#pragma rs reduce(init2_special0) initializer(init2_special0) accumulator(AccumInt)
34static void init2_special0(int *x, int *a) { }
35
36// initializer must take pointer parameter
37#pragma rs reduce(init_noptr) initializer(init_noptr) accumulator(AccumInt)
38static void init_noptr(int a) { }
39
40// initializer may be overloadable . . .
41#pragma rs reduce(init_over) initializer(init_over) accumulator(AccumInt)
42static __attribute__((overloadable)) void init_over(int *accum) { }
43
44// . . . but initializer must not have duplicate definitions
45#pragma rs reduce(init_dup) initializer(init_dup) accumulator(AccumInt)
46static __attribute__((overloadable)) void init_dup(int *accum) { }
47static __attribute__((overloadable)) void init_dup(unsigned int *accum) { }
48
49// initializer must be present
50#pragma rs reduce(init_missing) initializer(init_missing) accumulator(AccumInt)
51
52// initializer must be static
53#pragma rs reduce(init_nonstatic) initializer(init_nonstatic) accumulator(AccumInt)
54void init_nonstatic(int *accum) { }
55
56// initializer must return void
57#pragma rs reduce(init_nonvoid) initializer(init_nonvoid) accumulator(AccumInt)
58static int init_nonvoid(int *accum) { return 0; }
59
60// initializer parameter must point to non-const
61#pragma rs reduce(init_const) initializer(init_const) accumulator(AccumInt)
62static void init_const(const int *accum) { }
63
64// . . . but initializer parameter VALUE can be const
65#pragma rs reduce(init_valconst) initializer(init_valconst) accumulator(AccumInt)
66static void init_valconst(int *const accum) { }
67
68/////////////////////////////////////////////////////////////////////////////
69// accumulator
70/////////////////////////////////////////////////////////////////////////////
71
72// accumulator must take at least 2 parameters
73#pragma rs reduce(accum0) accumulator(accum0)
74static void accum0() { }
75
76// accumulator must take at least 2 parameters
77#pragma rs reduce(accum1) accumulator(accum1)
78static void accum1(int a) { }
79
80// accumulator first parameter must be of pointer type
81#pragma rs reduce(accum_noptr) accumulator(accum_noptr)
82static void accum_noptr(int accum, int val) { }
83
84// accumulator and initializer must take pointers to same type
85#pragma rs reduce(accum_vs_init) initializer(avi_init) accumulator(avi_accum)
86static void avi_init(int *accum) { }
87static void avi_accum(double *accum, int val) { }
88
89// accumulator must have at least 1 input
90#pragma rs reduce(accum_special) accumulator(accum_special)
91static void accum_special(int *accum, int x) { }
92
93// accumulator input must not be a pointer . . .
94#pragma rs reduce(accum_ptr) accumulator(accum_ptr) combiner(comb_ptr)
95static void accum_ptr(int *accum, char *val) { }
96static void comb_ptr(int *accum, const int *other) { }
97
98// . . . including a pointer from array decay
99#pragma rs reduce(accum_arr) accumulator(accum_arr) combiner(comb_arr)
100typedef char CharArray[10];
101static void accum_arr(int *accum, CharArray val) { }
102static void comb_arr(int *accum, const int *other) { }
103
104// accumulator input must not contain object type
105#pragma rs reduce(accum_obj) accumulator(accum_obj) combiner(comb_obj)
106static void accum_obj(int *accum, int val, rs_element elem) { }
107static void comb_obj(int *accum, const int *other) { }
108
109// accumulator may be overloadable . . .
110#pragma rs reduce(accum_over) accumulator(accum_over)
111static __attribute__((overloadable)) void accum_over(int *accum, int val) { }
112
113// . . . but accumulator must not have duplicate definitions
114#pragma rs reduce(accum_dup) accumulator(accum_dup)
115static __attribute__((overloadable)) void accum_dup(int *accum, int val) { }
116static __attribute__((overloadable)) void accum_dup(uint *accum, uint val) { }
117
118// accumulator must be present
119#pragma rs reduce(accum_missing) accumulator(accum_missing)
120
121// accumulator must be static
122#pragma rs reduce(accum_nonstatic) accumulator(accum_nonstatic)
123void accum_nonstatic(int *accum, int val) { }
124
125// accumulator must return void
126#pragma rs reduce(accum_nonvoid) accumulator(accum_nonvoid)
127static int accum_nonvoid(int *accum, int val) { return 0; }
128
129// first accumulator parameter must point to non-const . . .
130#pragma rs reduce(accum_const) accumulator(accum_const)
131static void accum_const(const int *accum, int val) { }
132
133// . . . but accumulator parameter VALUES can be const
134#pragma rs reduce(accum_valconst) accumulator(accum_valconst)
135static void accum_valconst(int *const accum, const int val) { }
136
137/////////////////////////////////////////////////////////////////////////////
138// combiner
139/////////////////////////////////////////////////////////////////////////////
140
141// combiner must take exactly 2 parameters
142#pragma rs reduce(comb0) accumulator(AccumInt) combiner(comb0)
143static void comb0() { }
144
145// combiner must take exactly 2 parameters
146#pragma rs reduce(comb1) accumulator(AccumInt) combiner(comb1)
147static void comb1(int *accum) { }
148
149// combiner must take exactly 2 parameters
150#pragma rs reduce(comb3) accumulator(AccumInt) combiner(comb3)
151static void comb3(int *accum, const int *otherA, int otherB) { }
152
153// combiner and accumulator must take pointers to same type
154#pragma rs reduce(comb_vs_accum) accumulator(cva_accum) combiner(cva_comb)
155static void cva_accum(int *accum, char val) { }
156static void cva_comb(unsigned *accum, const unsigned *other) { }
157
158// accumulator must have 1 input and no specials to omit combiner
159#pragma rs reduce(accum_2in) accumulator(accum_2in)
160static void accum_2in(int *accum, int in1, int in2) { }
161
162// accumulator must have 1 input and no specials to omit combiner
163#pragma rs reduce(accum_special_1in) accumulator(accum_special_1in)
164static void accum_special_1in(int *accum, int in1, int x) { }
165
166// accumulator parameter types must agree to omit combiner
167#pragma rs reduce(accum_types) accumulator(accum_types)
168static void accum_types(int *accum, unsigned val) { }
169
170// combiner may be overloadable . . .
171#pragma rs reduce(comb_over) accumulator(AccumInt) combiner(comb_over)
172static __attribute__((overloadable)) void comb_over(int *accum, const int *other) { }
173
174// . . . but combiner must not have duplicate definitions
175#pragma rs reduce(comb_dup) accumulator(AccumInt) combiner(comb_dup)
176static __attribute__((overloadable)) void comb_dup(int *accum, const int *other) { }
177static __attribute__((overloadable)) void comb_dup(uint *accum, const uint *other) { }
178
179// combiner must be present
180#pragma rs reduce(comb_missing) accumulator(AccumInt) combiner(comb_missing)
181
182// combiner must be static
183#pragma rs reduce(comb_nonstatic) accumulator(AccumInt) combiner(comb_nonstatic)
184void comb_nonstatic(int *accum, const int *other) { }
185
186// combiner must return void
187#pragma rs reduce(comb_nonvoid) accumulator(AccumInt) combiner(comb_nonvoid)
188static int comb_nonvoid(int *accum, const int *other) { return 0; }
189
190// first combiner parameter must point to non-const and second to const . . .
191#pragma rs reduce(comb_const) accumulator(AccumInt) combiner(comb_const)
192static void comb_const(const int *accum, int *other) { }
193
194// . . . but combiner parameter VALUES can be const
195#pragma rs reduce(comb_valconst) accumulator(AccumInt) combiner(comb_valconst)
196static void comb_valconst(int *const accum, const int *other) { }
197
198/////////////////////////////////////////////////////////////////////////////
199// outconverter
200/////////////////////////////////////////////////////////////////////////////
201
202// outconverter must take exactly 2 parameters
203#pragma rs reduce(out0) accumulator(AccumInt) outconverter(out0)
204static void out0() { }
205
206// outconverter must take exactly 2 parameters
207#pragma rs reduce(out1) accumulator(AccumInt) outconverter(out1)
208static void out1(char *out) { }
209
210// outconverter must take exactly 2 parameters
211#pragma rs reduce(out3) accumulator(AccumInt) outconverter(out3)
212static void out3(char *out, const int *val, int foo) { }
213
214// outconverter cannot take special parameter
215#pragma rs reduce(out_special) accumulator(AccumInt) outconverter(out_special)
216static void out_special(char *out, const int *y) { }
217
218// outconverter must take pointer
219#pragma rs reduce(out_ptr1) accumulator(AccumInt) outconverter(out_ptr1)
220static void out_ptr1(int out, const int *val) { }
221
222// outconverter must take pointer
223#pragma rs reduce(out_ptr2) accumulator(AccumInt) outconverter(out_ptr2)
224static void out_ptr2(int *out, const int val) { }
225
226// outconverter and accumulator must take pointers to same type
227#pragma rs reduce(out_vs_accum) accumulator(AccumInt) outconverter(ova_out)
228static void ova_out(int *out, const double *val) { }
229
230// outconverter may be overloadable . . .
231#pragma rs reduce(out_over) accumulator(AccumInt) outconverter(out_over)
232static __attribute__((overloadable)) void out_over(double *accum, const int *val) { }
233
234// . . . but outconverter must not have duplicate definitions
235#pragma rs reduce(out_dup) accumulator(AccumInt) outconverter(out_dup)
236static __attribute__((overloadable)) void out_dup(double *out, const int *val) { }
237static __attribute__((overloadable)) void out_dup(float *out, const int *val) { }
238
239// ouconverter must be present
240#pragma rs reduce(out_missing) accumulator(AccumInt) outconverter(out_missing)
241
242// outconverter must be static
243#pragma rs reduce(out_nonstatic) accumulator(AccumInt) outconverter(out_nonstatic)
244void out_nonstatic(int *out, const int *val) { }
245
246// outconverter must return void
247#pragma rs reduce(out_nonvoid) accumulator(AccumInt) outconverter(out_nonvoid)
248static int out_nonvoid(int *out, const int *val) { return 0; }
249
250// first outconverter parameter must point to non-const and second to const . . .
251#pragma rs reduce(out_const) accumulator(AccumInt) outconverter(out_const)
252static void out_const(const int *out, int *val) { }
253
254// . . . but outconverter parameter VALUES can be const
255#pragma rs reduce(out_valconst) accumulator(AccumInt) outconverter(out_valconst)
256static void out_valconst(int *const out, const int *val) { }
257