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