File: cwg1884.cpp

package info (click to toggle)
llvm-toolchain-21 1%3A21.1.6-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,245,028 kB
  • sloc: cpp: 7,619,726; ansic: 1,434,018; asm: 1,058,748; python: 252,740; f90: 94,671; objc: 70,685; lisp: 42,813; pascal: 18,401; sh: 8,601; ml: 5,111; perl: 4,720; makefile: 3,675; awk: 3,523; javascript: 2,409; xml: 892; fortran: 770
file content (643 lines) | stat: -rw-r--r-- 24,360 bytes parent folder | download | duplicates (5)
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
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: split-file --leading-lines %s %t
// RUN: %clang_cc1 -std=c++20 -pedantic-errors -fexceptions -fcxx-exceptions %t/cwg1884_A.cppm -triple x86_64-unknown-unknown -emit-module-interface -o %t/cwg1884_A.pcm
// RUN: %clang_cc1 -std=c++20 -verify=since-cxx20 -pedantic-errors -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown %t/cwg1884.cpp -fmodule-file=cwg1884_A=%t/cwg1884_A.pcm
// RUN: %clang_cc1 -std=c++23 -pedantic-errors -fexceptions -fcxx-exceptions %t/cwg1884_A.cppm -triple x86_64-unknown-unknown -emit-module-interface -o %t/cwg1884_A.pcm
// RUN: %clang_cc1 -std=c++23 -verify=since-cxx20 -pedantic-errors -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown %t/cwg1884.cpp -fmodule-file=cwg1884_A=%t/cwg1884_A.pcm
// RUN: %clang_cc1 -std=c++2c -pedantic-errors -fexceptions -fcxx-exceptions %t/cwg1884_A.cppm -triple x86_64-unknown-unknown -emit-module-interface -o %t/cwg1884_A.pcm
// RUN: %clang_cc1 -std=c++2c -verify=since-cxx20 -pedantic-errors -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown %t/cwg1884.cpp -fmodule-file=cwg1884_A=%t/cwg1884_A.pcm

// cwg1884: partial
// Cases b11, e11, g3, g4 are problematic, but we handle the other 101 cases fine.

// _N4993_.[basic.link]/11:
// For any two declarations of an entity E:
//   — If one declares E to be a variable or function,
//     the other shall declare E as one of the same type.
//   — If one declares E to be an enumerator, the other shall do so.
//   — If one declares E to be a namespace, the other shall do so.
//   — If one declares E to be a type,
//     the other shall declare E to be a type of the same kind (9.2.9.5).
//   — If one declares E to be a class template,
//     the other shall do so with the same kind and an equivalent template-head (13.7.7.2).
//     [Note 5 : The declarations can supply different default template arguments. — end note]
//   — If one declares E to be a function template or a (partial specialization of a) variable template,
//     the other shall declare E to be one with an equivalent template-head and type.
//   — If one declares E to be an alias template,
//     the other shall declare E to be one with an equivalent template-head and defining-type-id.
//   — If one declares E to be a concept, the other shall do so.
// Types are compared after all adjustments of types (during which typedefs (9.2.4) are replaced by their definitions);
// declarations for an array object can specify array types that differ by the presence or absence of a major array bound (9.3.4.5).
// No diagnostic is required if neither declaration is reachable from the other.

// The structure of the test is the following. First, module cwg1884_A
// provides all (significant) kinds of entities, each named 'a' through 'h', and copies of them.
// Then the .cpp file does MxN kind of testing, where it tests one kind of entity against every other kind.

//--- cwg1884_A.cppm
export module cwg1884_A;

export {
int a1;
int a2;
int a3;
int a4;
int a5;
int a6;
int a7;
int a8;
int a9;
int a10;
int a11;
void b1();
void b2();
void b3();
void b4();
void b5();
void b6();
void b7();
void b8();
void b9();
void b10();
void b11();
enum E {
  c1,
  c2, 
  c3,
  c4,
  c5,
  c6,
  c7,
  c8,
  c9,
  c10
};
namespace d1 {}
namespace d2 {}
namespace d3 {}
namespace d4 {}
namespace d5 {}
namespace d6 {}
namespace d7 {}
namespace d8 {}
namespace d9 {}
namespace d10 {}
struct e1;
struct e2;
struct e3;
struct e4;
struct e5;
struct e6;
struct e7;
struct e8;
struct e9;
struct e10;
struct e11;
struct e12;
struct e13;
template <typename>
class f1;
template <typename>
class f2;
template <typename>
class f3;
template <typename>
class f4;
template <typename>
class f5;
template <typename>
class f6;
template <typename>
class f7;
template <typename>
class f8;
template <typename>
class f9;
template <typename>
class f10;
template <typename>
class f11;
template <typename>
void g1(int);
template <typename>
void g2(int);
template <typename>
void g3(int);
template <typename>
void g4(int);
template <typename>
void g5(int);
template <typename>
void g6(int);
template <typename>
void g7(int);
template <typename>
void g8(int);
template <typename>
void g9(int);
template <typename>
void g10(int);
template <typename, typename>
int h1;
template <typename, typename>
int h2;
template <typename, typename>
int h3;
template <typename, typename>
int h4;
template <typename, typename>
int h5;
template <typename, typename>
int h6;
template <typename, typename>
int h7;
template <typename, typename>
int h8;
template <typename, typename>
int h9;
template <typename, typename>
int h10;
template <typename>
using i1 = int;
template <typename>
using i2 = int;
template <typename>
using i3 = int;
template <typename>
using i4 = int;
template <typename>
using i5 = int;
template <typename>
using i6 = int;
template <typename>
using i7 = int;
template <typename>
using i8 = int;
template <typename>
using i9 = int;
template <typename>
using i10 = int;
template <typename>
using i11 = int;
template <typename>
concept j1 = true;
template <typename>
concept j2 = true;
template <typename>
concept j3 = true;
template <typename>
concept j4 = true;
template <typename>
concept j5 = true;
template <typename>
concept j6 = true;
template <typename>
concept j7 = true;
template <typename>
concept j8 = true;
template <typename>
concept j9 = true;
template <typename>
concept j10 = true;
template <typename>
concept j11 = true;
} // export


//--- cwg1884.cpp
import cwg1884_A;

// FIXME: we don't diagnose several cases we should be. They are marked with MISSING prefix.

// Part A: matching against `int a;`
// ---------------------------------

void a1();
// since-cxx20-error@-1 {{redefinition of 'a1' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:42 {{previous definition is here}}
enum Ea {
  a2
  // since-cxx20-error@-1 {{redefinition of 'a2'}}
  //   since-cxx20-note@cwg1884_A.cppm:43 {{previous definition is here}}
};
namespace a3 {}
// since-cxx20-error@-1 {{redefinition of 'a3' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:44 {{previous definition is here}}
struct a4;
// @-1 OK, types and variables do not correspond
template <typename>
class a5;
// since-cxx20-error@-1 {{redefinition of 'a5' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:46 {{previous definition is here}}
template <typename>
void a6(int);
// since-cxx20-error@-1 {{redefinition of 'a6' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:47 {{previous definition is here}}
template <typename, typename>
int a7;
// since-cxx20-error@-1 {{redefinition of 'a7' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:48 {{previous definition is here}}
template <typename T>
int a8<T, int>;
// since-cxx20-error@-1 {{redefinition of 'a8' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:49 {{previous definition is here}}
// since-cxx20-error@-3 {{expected ';' after top level declarator}}
template <typename>
using a9 = int;
// since-cxx20-error@-1 {{redefinition of 'a9' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:50 {{previous definition is here}}
template <typename>
concept a10 = true;
// since-cxx20-error@-1 {{redefinition of 'a10' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:51 {{previous definition is here}}
// For variables, type has to match as well.
long a11;
// since-cxx20-error@-1 {{redefinition of 'a11' with a different type: 'long' vs 'int'}}
//   since-cxx20-note@cwg1884_A.cppm:52 {{previous definition is here}}


// Part B: matching against `void b();`
// ------------------------------------

int b1;
// since-cxx20-error@-1 {{redefinition of 'b1' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:53 {{previous definition is here}}
enum Eb {
  b2
  // since-cxx20-error@-1 {{redefinition of 'b2'}}
  //   since-cxx20-note@cwg1884_A.cppm:54 {{previous definition is here}}
};
namespace b3 {} // #cwg1884-namespace-b
// since-cxx20-error@-1 {{redefinition of 'b3' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:55 {{previous definition is here}}
struct b4;
// @-1 OK, types and functions do not correspond
template <typename>
class b5;
// since-cxx20-error@-1 {{redefinition of 'b5' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:57 {{previous definition is here}}
template <typename>
void b6(int);
// @-1 OK, a non-corresponding overload
template <typename, typename>
int b7;
// since-cxx20-error@-1 {{redefinition of 'b7' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:59 {{previous definition is here}}
template <typename T>
int b8<T, int>;
// since-cxx20-error@-1 {{no variable template matches partial specialization}}
template <typename>
using b9 = int;
// since-cxx20-error@-1 {{redefinition of 'b9' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:61 {{previous definition is here}}
template <typename>
concept b10 = true;
// since-cxx20-error@-1 {{redefinition of 'b10' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:62 {{previous definition is here}}
// For functions, type has to match as well.
// FIXME: we should be loud and clear here about type mismatch, like we do in `a11` case.
int b11();
// since-cxx20-error@-1 {{declaration of 'b11' in the global module follows declaration in module cwg1884_A}}
//   since-cxx20-note@cwg1884_A.cppm:63 {{previous declaration is here}}


// Part C: matching against `enum E { c };`
// ----------------------------------------

int c1;
// since-cxx20-error@-1 {{redefinition of 'c1' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:65 {{previous definition is here}}
void c2();
// since-cxx20-error@-1 {{redefinition of 'c2' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:66 {{previous definition is here}}
namespace c3 {}
// since-cxx20-error@-1 {{redefinition of 'c3' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:67 {{previous definition is here}}
struct c4;
// @-1 OK, types and enumerators do not correspond
template <typename>
class c5;
// since-cxx20-error@-1 {{redefinition of 'c5' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:69 {{previous definition is here}}
template <typename>
void c6(int);
// since-cxx20-error@-1 {{redefinition of 'c6' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:70 {{previous definition is here}}
template <typename, typename>
int c7;
// since-cxx20-error@-1 {{redefinition of 'c7' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:71 {{previous definition is here}}
template <typename T>
int c8<T, int>;
// since-cxx20-error@-1 {{redefinition of 'c8' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:72 {{previous definition is here}}
// since-cxx20-error@-3 {{expected ';' after top level declarator}}
template <typename>
using c9 = int;
// since-cxx20-error@-1 {{redefinition of 'c9' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:73 {{previous definition is here}}
template <typename>
concept c10 = true;
// since-cxx20-error@-1 {{redefinition of 'c10' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:74 {{previous definition is here}}


// Part D: matching against `namespace d {};`
// ------------------------------------------

int d1;
// since-cxx20-error@-1 {{redefinition of 'd1' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:76 {{previous definition is here}}
void d2();
// since-cxx20-error@-1 {{redefinition of 'd2' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:77 {{previous definition is here}}
enum Ed {
  d3
  // since-cxx20-error@-1 {{redefinition of 'd3'}}
  //   since-cxx20-note@cwg1884_A.cppm:78 {{previous definition is here}}
};
struct d4;
// since-cxx20-error@-1 {{redefinition of 'd4' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:79 {{previous definition is here}}
template <typename>
class d5;
// since-cxx20-error@-1 {{redefinition of 'd5' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:80 {{previous definition is here}}
template <typename>
void d6(int);
// since-cxx20-error@-1 {{redefinition of 'd6' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:81 {{previous definition is here}}
template <typename, typename>
int d7;
// since-cxx20-error@-1 {{redefinition of 'd7' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:82 {{previous definition is here}}
template <typename T>
int d8<T, int>;
// since-cxx20-error@-1 {{redefinition of 'd8' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:83 {{previous definition is here}}
// since-cxx20-error@-3 {{expected ';' after top level declarator}}
template <typename>
using d9 = int;
// since-cxx20-error@-1 {{redefinition of 'd9' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:84 {{previous definition is here}}
template <typename>
concept d10 = true;
// since-cxx20-error@-1 {{redefinition of 'd10' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:85 {{previous definition is here}}


// Part E: matching against `struct e;`
// ------------------------------------

int e1;
// @-1 OK, types and variables do not correspond
void e2();
// @-1 OK, types and functions do not correspond
enum Ee {
  e3
  // @-1 OK, types and enumerators do not correspond
};
namespace e4 {}
// since-cxx20-error@-1 {{redefinition of 'e4' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:89 {{previous definition is here}}
template <typename>
class e5;
// since-cxx20-error@-1 {{redefinition of 'e5' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:90 {{previous definition is here}}
template <typename>
void e6(int);
// @-1 OK, types and function templates do not correspond
template <typename, typename>
int e7;
// since-cxx20-error@-1 {{redefinition of 'e7' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:92 {{previous definition is here}}
template <typename T>
int e8<T, int>;
// since-cxx20-error@-1 {{redefinition of 'e8' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:93 {{previous definition is here}}
// since-cxx20-error@-3 {{expected ';' after top level declarator}}
template <typename>
using e9 = int;
// since-cxx20-error@-1 {{redefinition of 'e9' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:94 {{previous definition is here}}
template <typename>
concept e10 = true;
// since-cxx20-error@-1 {{redefinition of 'e10' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:95 {{previous definition is here}}
// FIXME: the following forward declaration is well-formed.
//        Agreement on 'struct' vs 'class' is not required per [dcl.type.elab]/7.
class e11;
// since-cxx20-error@-1 {{declaration of 'e11' in the global module follows declaration in module cwg1884_A}}
//   since-cxx20-note@cwg1884_A.cppm:96 {{previous declaration is here}}
union e12;
// since-cxx20-error@-1 {{use of 'e12' with tag type that does not match previous declaration}}
//   since-cxx20-note@cwg1884_A.cppm:97 {{previous use is here}}
// since-cxx20-error@-3 {{declaration of 'e12' in the global module follows declaration in module cwg1884_A}}
//   since-cxx20-note@cwg1884_A.cppm:97 {{previous declaration is here}}
enum e13 {};
// since-cxx20-error@-1 {{use of 'e13' with tag type that does not match previous declaration}}
//   since-cxx20-note@cwg1884_A.cppm:98 {{previous use is here}}


// Part F: matching against `template <typename> class f;`
// -------------------------------------------------------

int f1;
// since-cxx20-error@-1 {{redefinition of 'f1' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:100 {{previous definition is here}}
void f2();
// since-cxx20-error@-1 {{redefinition of 'f2' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:102 {{previous definition is here}}
enum Ef {
  f3
  // since-cxx20-error@-1 {{redefinition of 'f3'}}
  //   since-cxx20-note@cwg1884_A.cppm:104 {{previous definition is here}}
};
namespace f4 {}
// since-cxx20-error@-1 {{redefinition of 'f4' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:106 {{previous definition is here}}
struct f5;
// since-cxx20-error@-1 {{redefinition of 'f5' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:108 {{previous definition is here}}
template <typename>
void f6(int);
// since-cxx20-error@-1 {{redefinition of 'f6' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:110 {{previous definition is here}}
template <typename, typename>
int f7;
// since-cxx20-error@-1 {{redefinition of 'f7' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:112 {{previous definition is here}}
template <typename T>
int f8<T, int>;
// since-cxx20-error@-1 {{no variable template matches partial specialization}}
template <typename>
using f9 = int;
// since-cxx20-error@-1 {{redefinition of 'f9' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:116 {{previous definition is here}}
template <typename>
concept f10 = true;
// since-cxx20-error@-1 {{redefinition of 'f10' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:118 {{previous definition is here}}


// Part G: matching against `template <typename> void g(int);`
// -----------------------------------------------------------

int g1;
// since-cxx20-error@-1 {{redefinition of 'g1' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:122 {{previous definition is here}}
void g2();
// @-1 OK, a non-corresponding overload
enum Eg {
  g3
  // MISSING-since-cxx20-error@-1 {{redefinition of 'g3'}}
  //   MISSING-since-cxx20-note@cwg1884_A.cppm:126 {{previous definition is here}}
};
namespace g4 {}
// MISSING-since-cxx20-error@-1 {{redefinition of 'g4' as different kind of symbol}}
//   MISSING-since-cxx20-note@cwg1884_A.cppm:128 {{previous definition is here}}
struct g5;
// @-1 OK, types and function templates do not correspond
template <typename>
class g6;
// since-cxx20-error@-1 {{redefinition of 'g6' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:132 {{previous definition is here}}
template <typename, typename>
int g7;
// since-cxx20-error@-1 {{redefinition of 'g7' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:134 {{previous definition is here}}
template <typename T>
int g8<T, int>;
// since-cxx20-error@-1 {{no variable template matches specialization; did you mean to use 'g8' as function template instead?}}
template <typename>
using g9 = int;
// since-cxx20-error@-1 {{redefinition of 'g9' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:138 {{previous definition is here}}
template <typename>
concept g10 = true;
// since-cxx20-error@-1 {{redefinition of 'g10' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:140 {{previous definition is here}}


// Part H: matching against `template <typename, typename> int h;`
// ---------------------------------------------------------------

int h1;
// since-cxx20-error@-1 {{redefinition of 'h1' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:142 {{previous definition is here}}
void h2();
// since-cxx20-error@-1 {{redefinition of 'h2' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:144 {{previous definition is here}}
enum Eh {
  h3
  // since-cxx20-error@-1 {{redefinition of 'h3'}}
  //   since-cxx20-note@cwg1884_A.cppm:146 {{previous definition is here}}
};
namespace h4 {}
// since-cxx20-error@-1 {{redefinition of 'h4' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:148 {{previous definition is here}}
struct h5;
// since-cxx20-error@-1 {{redefinition of 'h5' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:150 {{previous definition is here}}
template <typename>
class h6;
// since-cxx20-error@-1 {{redefinition of 'h6' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:152 {{previous definition is here}}
template <typename>
void h7(int);
// since-cxx20-error@-1 {{redefinition of 'h7' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:154 {{previous definition is here}}
template <typename T>
int h8<T, int>;
// @-1 OK, partial specialization
template <typename>
using h9 = int;
// since-cxx20-error@-1 {{redefinition of 'h9' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:158 {{previous definition is here}}
template <typename>
concept h10 = true;
// since-cxx20-error@-1 {{redefinition of 'h10' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:160 {{previous definition is here}}


// Part I: matching against `template <typename> using i = int;`
// -------------------------------------------------------------

int i1;
// since-cxx20-error@-1 {{redefinition of 'i1' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:162 {{previous definition is here}}
void i2();
// since-cxx20-error@-1 {{redefinition of 'i2' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:164 {{previous definition is here}}
enum Ei {
  i3
  // since-cxx20-error@-1 {{redefinition of 'i3'}}
  //   since-cxx20-note@cwg1884_A.cppm:166 {{previous definition is here}}
};
namespace i4 {}
// since-cxx20-error@-1 {{redefinition of 'i4' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:168 {{previous definition is here}}
struct i5;
// since-cxx20-error@-1 {{redefinition of 'i5' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:170 {{previous definition is here}}
template <typename>
class i6;
// since-cxx20-error@-1 {{redefinition of 'i6' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:172 {{previous definition is here}}
template <typename>
void i7(int);
// since-cxx20-error@-1 {{redefinition of 'i7' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:174 {{previous definition is here}}
template <typename, typename>
int i8;
// since-cxx20-error@-1 {{redefinition of 'i8' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:176 {{previous definition is here}}
template <typename T>
int i9<T, int>;
// since-cxx20-error@-1 {{no variable template matches partial specialization}}
template <typename>
concept i10 = true;
// since-cxx20-error@-1 {{redefinition of 'i10' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:180 {{previous definition is here}}


// Part J: matching against `template <typename> concept j = true;`
// ----------------------------------------------------------------

int j1;
// since-cxx20-error@-1 {{redefinition of 'j1' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:184 {{previous definition is here}}
void j2();
// since-cxx20-error@-1 {{redefinition of 'j2' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:186 {{previous definition is here}}
enum Ej {
  j3
  // since-cxx20-error@-1 {{redefinition of 'j3'}}
  //   since-cxx20-note@cwg1884_A.cppm:188 {{previous definition is here}}
};
namespace j4 {}
// since-cxx20-error@-1 {{redefinition of 'j4' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:190 {{previous definition is here}}
struct j5;
// since-cxx20-error@-1 {{redefinition of 'j5' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:192 {{previous definition is here}}
template <typename>
class j6;
// since-cxx20-error@-1 {{redefinition of 'j6' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:194 {{previous definition is here}}
template <typename>
void j7(int);
// since-cxx20-error@-1 {{redefinition of 'j7' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:196 {{previous definition is here}}
template <typename, typename>
int j8;
// since-cxx20-error@-1 {{redefinition of 'j8' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:198 {{previous definition is here}}
template <typename T>
int j9<T, int>;
// since-cxx20-error@-1 {{no variable template matches partial specialization}}
template <typename>
using j10 = int;
// since-cxx20-error@-1 {{redefinition of 'j10' as different kind of symbol}}
//   since-cxx20-note@cwg1884_A.cppm:202 {{previous definition is here}}