source: tests/array-collections/dimexpr-match.hfa@ b28ce93

Last change on this file since b28ce93 was 090b076, checked in by Michael Brooks <mlbrooks@…>, 8 months ago

Expand and update comments re testing instrucions

  • Property mode set to 100644
File size: 12.2 KB
Line 
1
2
3// Framework for the dimexpr-match tests.
4//
5// For general test-suite maintenance instrutions, see *-detail.sh.
6//
7// These tests show whether an expression of type like `float (*)[25]`
8// can be used in a context expecting a type like `float (*)[rand()]`.
9//
10// A test includes this header and defines the function `runTests`.
11// The `runTests` body is made with macros defined here.
12//
13// Normally, drive a test either from test.py or ./dimexpr-match-detail.sh.
14// Direct usage is for making small repro cases, while troubleshooting a problem.
15//
16// Direct usage is:
17//
18// compiler=gcc -x c # pick one
19// compiler=$cfa
20//
21// test=dimexpr-match-c.cfa # pick one
22// test=dimexpr-match-cfa.cfa
23//
24// $compiler $test
25// ./a.out
26// ./a.out -cmd4skip | sed -E -n 's/skip.*\| *//p'
27//
28// Expect the above compiler invocation to report success.
29// Expect the first a.out invocation to print a mix of "done" and "skipped" messages.
30// Assume the second a.out invocation (through sed) prints several compiler CLI invocations. For each...
31// Expect that running the current compiler invocation reports an error.
32// So far, this is what dimexpr-match-detail.sh does.
33//
34// The macro logic in here is hard to read.
35// A specific test's TRY_COMPAT definition is easy to read.
36//
37// An error message from an unexpected rejection is hard to read, because the message blames a macro.
38// To diagnose one, first obtain the failing case's coordinates by ruuning:
39// $compiler $test -E -P -DEMIT_COORDS > temp.cfa # just preprocessor
40// $compiler temp.cfa # will fail, want message
41// Open temp.cfa and chase an error detail's line number, to find the failing code.
42// Look at the pragma-message above the failing line, and read off the failure's -D coordinates.
43// Isolate this case by running: ... copied from pragma message ...............................................................................................
44// $compiler $test -E -P -DEMIT_MINIMAL -DINCLUDE_MINIMAL -DARRANGEMENT__OPTIN -DARRANGEMENT_PTRPARM_---- -DCASE_MANUAL -DCASE_FORMATION_L=--- -DCASE_FORMATION_R=--- -DCASE_EQUALITY=-- > mycase.cfa # template
45// $compiler $test -E -P -DEMIT_MINIMAL -DINCLUDE_MINIMAL -DARRANGEMENT__OPTIN -DARRANGEMENT_PTRPARM_CALL -DCASE_MANUAL -DCASE_FORMATION_L=LIT -DCASE_FORMATION_R=LIT -DCASE_EQUALITY=NE > mycase.cfa # example
46// $compiler mycase.cfa
47// The content of mycase.cfa is easy to read.
48
49#ifdef __cforall
50 extern "C" {
51 int strcmp (const char* str1, const char* str2);
52 }
53 #define NULL 0p
54#else
55 #include <stdio.h>
56 #include <string.h>
57#endif
58
59#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
60#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
61
62#define DO_PRAGMA(x) _Pragma (#x)
63#define DO_MESSAGE(x) DO_PRAGMA(message #x)
64
65#ifdef EMIT_COORDS
66#define MAYPRINT(...)
67#define MAYDELIMIT( LV, RV, KL, KR, FL, FR, ISEQ, ARR_NAME ) \
68 DO_MESSAGE(-DARRANGEMENT__OPTIN -DARRANGEMENT_ ## ARR_NAME -DCASE_MANUAL -DCASE_FORMATION_L=KL -DCASE_FORMATION_R=KR -DCASE_EQUALITY=ISEQ)
69#else
70#define MAYPRINT(...) printf(__VA_ARGS__);
71#define MAYDELIMIT( LV, RV, KL, KR, FL, FR, ISEQ, ARR_NAME )
72#endif
73
74#ifdef EMIT_MINIMAL
75#undef MAYPRINT
76#define MAYPRINT(...)
77#endif
78
79#define GRP_K_LIT STA
80#define GRP_K_ENU STA
81#define GRP_K_CPR DYN
82#define GRP_K_DIM DYN
83#define GRP_K_MUT UNS
84#define GRP_K( K ) GRP_K_ ## K
85
86#define MKV7_LIT 7
87#define MKV7_ENU enu7
88#define MKV7_CPR cpr7
89#define MKV7_DIM dim7
90#define MKV7_MUT mut7
91#define MKV7( K ) MKV7_ ## K
92
93#define MKV42_LIT 42
94#define MKV42_ENU enu42
95#define MKV42_CPR cpr42
96#define MKV42_DIM dim42
97#define MKV42_MUT mut42
98#define MKV42( K ) MKV42_ ## K
99
100#define MKLV( LK ) MKV7( LK )
101
102#define MKRV_EQ( KR ) MKV7(KR)
103#define MKRV_NE( KR ) MKV42(KR)
104#define MKRV( KR, ISEQ ) MKRV_ ## ISEQ( KR )
105
106#ifdef __cforall
107#define RULE_PFX RULE_CF_
108#else
109#define RULE_PFX RULE_C_
110#endif
111
112#define X_CASE_2( KL, KR, ISEQ, FL, FR, ARR_NAME ) \
113 MAY_TRY_COMPAT( \
114 CAT(CAT(CAT(CAT(CAT(RULE_PFX, ISEQ), _), FL), _), FR), \
115 MKLV( KL ), \
116 MKRV( KR, ISEQ ), \
117 KL, KR, FL, FR, ISEQ, ARR_NAME \
118 )
119
120#define X_CASE( KL, KR, ISEQ, ARR_NAME ) X_CASE_2( KL, KR, ISEQ, GRP_K(KL), GRP_K(KR), ARR_NAME )
121
122#ifdef ERRS
123#define MAY_TRY_COMPAT_REJ( LV, RV, KL, KR, FL, FR, ISEQ, ARR_NAME ) \
124 _Pragma("message \"Expect fail\"") \
125 MAY_TRY_COMPAT_ACC( LV, RV, KL, KR, FL, FR, ISEQ, ARR_NAME )
126#else
127#define MAY_TRY_COMPAT_REJ( LV, RV, KL, KR, FL, FR, ISEQ, ARR_NAME ) \
128 MAYPRINT("skip %s %s %s, L=%s, R=%s", #FL, #ISEQ, #FR, #LV, #RV ) \
129 if (cmd4skip) { \
130 MAYPRINT(" | -DERRS -Werror %s -DARRANGEMENT__OPTIN -DARRANGEMENT_%s -DCASE_MANUAL -DCASE_FORMATION_L=%s -DCASE_FORMATION_R=%s -DCASE_EQUALITY=%s", __FILE__, #ARR_NAME, #KL, #KR, #ISEQ ) \
131 } \
132 MAYPRINT("\n")
133#endif
134
135#define MAY_TRY_COMPAT_ACC( LV, RV, KL, KR, FL, FR, ISEQ, ARR_NAME ) \
136 MAYDELIMIT( LV, RV, KL, KR, FL, FR, ISEQ, ARR_NAME ) \
137 TRY_COMPAT(LV, RV) \
138 MAYPRINT("done %s %s %s, L=%s, R=%s\n", #FL, #ISEQ, #FR, #LV, #RV )
139
140#define MAY_TRY_COMPAT(EXPECT, LV, RV, KL, KR, FL, FR, ISEQ, ARR_NAME) \
141 CAT(MAY_TRY_COMPAT_, EXPECT( LV, RV, KL, KR, FL, FR, ISEQ, ARR_NAME ))
142
143#define TCXXX(Q) Q
144#define TCXX(Q) #Q
145
146#define QUOTE(str) #str
147#define EXPAND_AND_QUOTE(str) QUOTE(str)
148#define TRY_COMPAT_E EXPAND_AND_QUOTE(TRY_COMPAT(__L__,__R__))
149
150#if ! defined __cforall
151#define SUPPRESS_FORALL_N
152#endif
153
154#if defined SUPPRESS_FORALL_N_ON_CLASSIC && defined CFA_IS_CLASSIC
155#define SUPPRESS_FORALL_N
156#endif
157
158/*
159
160RULE macros define the expected outcome:
161Given a compiler's functionality level and a test case, do we expect the compiler to accept or reject the case?
162
163Group STA: Statically stable
164 - literal
165 - enumeration
166
167Group DYN: Dynamically stable
168 - parameter that is a constant
169 - static constant global
170
171Group UNS: potentially Unstable
172 - variable
173 - parameter that is a constant reference to constant
174 - function return
175 - extern constant (safe and annoying here; must be here if you can link it to something that changes)
176
177C rules
178 - Reject a pair from group STA if it has two different values
179 - otherwise, accept
180
181CFA "classic" rules (what CFA actually does, before Mike brings in CFA rules)
182 - same as C, except
183 - reject STA/non-STA crossing
184
185CFA rules
186 - accept a pair from group STA if it has the same value
187 - accept a pair from group DYN if it is written out the same (e.g. refers to same variable)
188 - otherwise, reject
189 (notably, reject all group UNS)
190 (notably, reject any group crossing)
191
192The RULE_* definitions below encode the summary above into the test harness's format.
193This format is: tabled function to {ACC,REJ} from {STA,DYN,UNS}^2 x {EQ,NE}
194
195*/
196
197#define RULE_C_EQ_STA_STA ACC
198#define RULE_C_EQ_STA_DYN ACC
199#define RULE_C_EQ_STA_UNS ACC
200#define RULE_C_EQ_DYN_STA ACC
201#define RULE_C_EQ_DYN_DYN ACC
202#define RULE_C_EQ_DYN_UNS ACC
203#define RULE_C_EQ_UNS_STA ACC
204#define RULE_C_EQ_UNS_DYN ACC
205#define RULE_C_EQ_UNS_UNS ACC
206
207#define RULE_C_NE_STA_STA REJ
208#define RULE_C_NE_STA_DYN ACC
209#define RULE_C_NE_STA_UNS ACC
210#define RULE_C_NE_DYN_STA ACC
211#define RULE_C_NE_DYN_DYN ACC
212#define RULE_C_NE_DYN_UNS ACC
213#define RULE_C_NE_UNS_STA ACC
214#define RULE_C_NE_UNS_DYN ACC
215#define RULE_C_NE_UNS_UNS ACC
216
217#ifdef CFA_IS_CLASSIC
218
219#define RULE_CF_EQ_STA_STA ACC
220#define RULE_CF_EQ_STA_DYN REJ
221#define RULE_CF_EQ_STA_UNS REJ
222#define RULE_CF_EQ_DYN_STA REJ
223#define RULE_CF_EQ_DYN_DYN ACC
224#define RULE_CF_EQ_DYN_UNS ACC
225#define RULE_CF_EQ_UNS_STA REJ
226#define RULE_CF_EQ_UNS_DYN ACC
227#define RULE_CF_EQ_UNS_UNS ACC
228
229#define RULE_CF_NE_STA_STA REJ
230#define RULE_CF_NE_STA_DYN REJ
231#define RULE_CF_NE_STA_UNS REJ
232#define RULE_CF_NE_DYN_STA REJ
233#define RULE_CF_NE_DYN_DYN ACC
234#define RULE_CF_NE_DYN_UNS ACC
235#define RULE_CF_NE_UNS_STA REJ
236#define RULE_CF_NE_UNS_DYN ACC
237#define RULE_CF_NE_UNS_UNS ACC
238
239#else
240
241#define RULE_CF_EQ_STA_STA ACC
242#define RULE_CF_EQ_STA_DYN REJ
243#define RULE_CF_EQ_STA_UNS REJ
244#define RULE_CF_EQ_DYN_STA REJ
245#define RULE_CF_EQ_DYN_DYN ACC
246#define RULE_CF_EQ_DYN_UNS REJ
247#define RULE_CF_EQ_UNS_STA REJ
248#define RULE_CF_EQ_UNS_DYN REJ
249#define RULE_CF_EQ_UNS_UNS REJ
250
251#define RULE_CF_NE_STA_STA REJ
252#define RULE_CF_NE_STA_DYN REJ
253#define RULE_CF_NE_STA_UNS REJ
254#define RULE_CF_NE_DYN_STA REJ
255#define RULE_CF_NE_DYN_DYN REJ
256#define RULE_CF_NE_DYN_UNS REJ
257#define RULE_CF_NE_UNS_STA REJ
258#define RULE_CF_NE_UNS_DYN REJ
259#define RULE_CF_NE_UNS_UNS REJ
260
261#endif
262
263#ifndef ARRANGEMENT__OPTIN
264#define ARRANGEMENT_PTRVAR_INIT 1
265#define ARRANGEMENT_PTRPARM_CALL 1
266#define ARRANGEMENT_PTRVAR_ASGN 1
267#define ARRANGEMENT_REFVAR_INIT 1
268#define ARRANGEMENT_REFPARM_CALL 1
269#define ARRANGEMENT_REFVAR_ASGN 1
270#define ARRANGEMENT_CALLZIP 1
271#endif
272
273#define EMIT_SKIP( ARR_NAME ) \
274 MAYPRINT( "---- " #ARR_NAME " skipped\n" )
275
276#define MAY_EMIT_ARRANGEMENT_PTRVAR_INIT( ARR_NAME ) EMIT_SKIP( ARR_NAME )
277#define MAY_EMIT_ARRANGEMENT_PTRPARM_CALL( ARR_NAME ) EMIT_SKIP( ARR_NAME )
278#define MAY_EMIT_ARRANGEMENT_PTRVAR_ASGN( ARR_NAME ) EMIT_SKIP( ARR_NAME )
279#define MAY_EMIT_ARRANGEMENT_REFVAR_INIT( ARR_NAME ) EMIT_SKIP( ARR_NAME )
280#define MAY_EMIT_ARRANGEMENT_REFPARM_CALL( ARR_NAME ) EMIT_SKIP( ARR_NAME )
281#define MAY_EMIT_ARRANGEMENT_REFVAR_ASGN( ARR_NAME ) EMIT_SKIP( ARR_NAME )
282#define MAY_EMIT_ARRANGEMENT_CALLZIP( ARR_NAME ) EMIT_SKIP( ARR_NAME )
283
284#define MAY_EMIT_1( ARR_NAME ) \
285 MAYPRINT( "---- " #ARR_NAME ": " TRY_COMPAT_E "\n" ) \
286 RUNCASES( ARR_NAME )
287
288#ifndef CASE_MANUAL
289 #define RUNCASES( ARR_NAME ) \
290 X_CASE( LIT, LIT, EQ, ARR_NAME ) \
291 X_CASE( LIT, LIT, NE, ARR_NAME ) \
292 X_CASE( LIT, ENU, EQ, ARR_NAME ) \
293 X_CASE( LIT, ENU, NE, ARR_NAME ) \
294 X_CASE( LIT, CPR, NE, ARR_NAME ) \
295 X_CASE( LIT, MUT, NE, ARR_NAME ) \
296 X_CASE( ENU, ENU, EQ, ARR_NAME ) \
297 X_CASE( ENU, ENU, NE, ARR_NAME ) \
298 X_CASE( ENU, LIT, EQ, ARR_NAME ) \
299 X_CASE( ENU, LIT, NE, ARR_NAME ) \
300 X_CASE( ENU, CPR, NE, ARR_NAME ) \
301 X_CASE( ENU, MUT, NE, ARR_NAME ) \
302 X_CASE( CPR, CPR, EQ, ARR_NAME ) \
303 X_CASE( CPR, CPR, NE, ARR_NAME ) \
304 X_CASE( CPR, LIT, NE, ARR_NAME ) \
305 X_CASE( CPR, ENU, NE, ARR_NAME ) \
306 X_CASE( CPR, MUT, NE, ARR_NAME ) \
307 X_CASE( MUT, MUT, EQ, ARR_NAME ) \
308 X_CASE( MUT, MUT, NE, ARR_NAME ) \
309 X_CASE( MUT, LIT, NE, ARR_NAME ) \
310 X_CASE( MUT, ENU, NE, ARR_NAME ) \
311 X_CASE( MUT, CPR, NE, ARR_NAME ) \
312 RUNCASES_FORALL_N( ARR_NAME )
313
314 #ifndef SUPPRESS_FORALL_N
315 #define RUNCASES_FORALL_N( ARR_NAME ) \
316 X_CASE( LIT, DIM, NE, ARR_NAME ) \
317 X_CASE( ENU, DIM, NE, ARR_NAME ) \
318 X_CASE( CPR, DIM, NE, ARR_NAME ) \
319 X_CASE( DIM, DIM, EQ, ARR_NAME ) \
320 X_CASE( DIM, DIM, NE, ARR_NAME ) \
321 X_CASE( DIM, LIT, NE, ARR_NAME ) \
322 X_CASE( DIM, ENU, NE, ARR_NAME ) \
323 X_CASE( DIM, CPR, NE, ARR_NAME ) \
324 X_CASE( DIM, MUT, NE, ARR_NAME ) \
325 X_CASE( MUT, DIM, NE, ARR_NAME )
326 #else
327 #define RUNCASES_FORALL_N( ARR_NAME )
328 #endif
329
330#else
331 #ifndef CASE_FORMATION_L
332 #error CASE_FORMATION_L not specified along with CASE_MANUAL
333 #endif
334 #ifndef CASE_FORMATION_R
335 #error CASE_FORMATION_R not specified along with CASE_MANUAL
336 #endif
337 #ifndef CASE_EQUALITY
338 #error CASE_EQUALITY not specified along with CASE_MANUAL
339 #endif
340 #define RUNCASES( ARR_NAME ) X_CASE( CASE_FORMATION_L, CASE_FORMATION_R, CASE_EQUALITY, ARR_NAME )
341#endif
342
343#define ARRANGEMENT( ARR_NAME ) CAT(MAY_EMIT_, CAT(ARRANGEMENT_, ARR_NAME)) ( ARR_NAME )
344
345
346#if defined SUPPRESS_FORALL_N
347
348 #define DECLN_runTests \
349 void runTests( \
350 const int cpr7, const int cpr42, \
351 int cmd4skip \
352 )
353#else
354
355 forall( [N] ) struct quicktag {};
356
357 #define DECLN_runTests \
358 forall( [dim7], [dim42] ) \
359 void runTests( \
360 const int cpr7, const int cpr42, \
361 quicktag(dim7), quicktag(dim42), \
362 int cmd4skip \
363 )
364#endif
365
366DECLN_runTests;
367
368int main(int argc, const char *argv[]) {
369
370 int cmd4skip = 0;
371
372 if (argc > 1 && strcmp("-cmd4skip", argv[1]) == 0) {
373 cmd4skip = 1;
374 }
375
376 #if defined SUPPRESS_FORALL_N
377 runTests(7, 42, cmd4skip);
378 #else
379 quicktag(7) tag7;
380 quicktag(42) tag42;
381 runTests(7, 42, tag7, tag42, cmd4skip);
382 #endif
383
384 return 0;
385}
Note: See TracBrowser for help on using the repository browser.