-
Notifications
You must be signed in to change notification settings - Fork 10.8k
/
dr3xx.cpp
1792 lines (1586 loc) · 64.1 KB
/
dr3xx.cpp
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
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// RUN: %clang_cc1 -std=c++23 -verify=expected,cxx20-23,cxx23,since-cxx11,since-cxx17,since-cxx23 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++20 -verify=expected,cxx98-20,cxx20-23,since-cxx11,since-cxx17 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++17 -verify=expected,cxx98-17,cxx98-20,since-cxx11,since-cxx17 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++14 -verify=expected,cxx98-14,cxx98-17,cxx98-20,cxx11-14,since-cxx11 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++11 -verify=expected,cxx98-14,cxx98-17,cxx98-20,cxx11-14,since-cxx11 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++98 -verify=expected,cxx98-14,cxx98-17,cxx98-20,cxx98 -triple %itanium_abi_triple %s -fexceptions -fcxx-exceptions -pedantic-errors
namespace cwg300 { // cwg300: yes
template<typename R, typename A> void f(R (&)(A)) {}
int g(int);
void h() { f(g); }
}
namespace cwg301 { // cwg301: 3.5
// see also cwg38
struct S;
template<typename T> void operator+(T, T);
void operator-(S, S);
void f() {
bool a = (void(*)(S, S))operator+<S> < (void(*)(S, S))operator+<S>;
// expected-warning@-1 {{ordered comparison of function pointers ('void (*)(S, S)' and 'void (*)(S, S)')}}
bool b = (void(*)(S, S))operator- < (void(*)(S, S))operator-;
// cxx98-17-warning@-1 {{ordered comparison of function pointers ('void (*)(S, S)' and 'void (*)(S, S)')}}
// cxx20-23-error@-2 {{expected '>'}}
// cxx20-23-note@-3 {{to match this '<'}}
bool c = (void(*)(S, S))operator+ < (void(*)(S, S))operator-;
// expected-error@-1 {{expected '>'}}
// expected-note@-2 {{to match this '<'}}
}
template<typename T> void f() {
// FIXME: We are emitting a lot of bogus diagnostics here.
typename T::template operator+<int> a;
// expected-error@-1 {{typename specifier refers to a non-type template}}
// expected-error@-2 {{'template' keyword not permitted here}}
// expected-error@-3 {{a type specifier is required for all declarations}}
// expected-error@-4 {{'operator+' cannot be the name of a variable or data member}}
// expected-error@-5 {{expected ';' at end of declaration}}
// FIXME: This shouldn't say (null).
class T::template operator+<int> b;
// expected-error@-1 {{identifier followed by '<' indicates a class template specialization but (null) refers to a function template}}
enum T::template operator+<int> c;
// expected-error@-1 {{expected identifier}}
enum T::template operator+<int>::E d;
// expected-error@-1 {{qualified name refers into a specialization of function template 'T::template operator +'}}
// expected-error@-2 {{ISO C++ forbids forward references to 'enum' types}}
enum T::template X<int>::E e;
T::template operator+<int>::foobar();
// expected-error@-1 {{qualified name refers into a specialization of function template 'T::template operator +'}}
T::template operator+<int>(0); // ok
}
// FIXME: We are emitting a bunch of bogus diagnostics for the next 3 lines.
// All of them do a bad job at explaining that 'class' is not allowed here.
template<typename T> class operator&<T*> {};
// expected-error@-1 {{declaration of anonymous class must be a definition}}
// expected-error@-2 {{declaration does not declare anything}}
template<typename T> class T::operator& {};
// expected-error@-1 {{expected identifier}}
// expected-error@-2 {{declaration of anonymous class must be a definition}}
// expected-error@-3 {{declaration does not declare anything}}
template<typename T> class S::operator&<T*> {};
// expected-error@-1 {{expected identifier}}
// expected-error@-2 {{declaration of anonymous class must be a definition}}
// expected-error@-3 {{declaration does not declare anything}}
}
namespace cwg302 { // cwg302: 3.0
struct A { A(); ~A(); };
#if __cplusplus < 201103L
struct B {
// expected-error@-1 {{implicit default constructor for 'cwg302::B' must explicitly initialize the const member 'n'}}
// expected-note@#cwg302-b {{in implicit default constructor for 'cwg302::B' first required here}}
// expected-note@#cwg302-B-n {{declared here}}
const int n; // #cwg302-B-n
A a;
} b = B(); // #cwg302-b
// Trivial default constructor C::C() is not called here.
struct C {
const int n;
} c = C();
#else
struct B {
const int n; // #cwg302-B-n
A a;
} b = B();
// expected-error@-1 {{call to implicitly-deleted default constructor of 'B'}}
// expected-note@#cwg302-B-n {{default constructor of 'B' is implicitly deleted because field 'n' of const-qualified type 'const int' would not be initialized}}
// C::C() is called here, because even though it's trivial, it's deleted.
struct C {
const int n; // #cwg302-C-n
} c = C();
// expected-error@-1 {{call to implicitly-deleted default constructor of 'C'}}
// expected-note@#cwg302-C-n {{default constructor of 'C' is implicitly deleted because field 'n' of const-qualified type 'const int' would not be initialized}}
struct D {
const int n = 0;
} d = D();
#endif
}
// cwg303: na
namespace cwg304 { // cwg304: 2.9
typedef int &a;
int n = a();
// expected-error@-1 {{reference to type 'int' requires an initializer}}
struct S { int &b; }; // #cwg304-S
// cxx98-error@-1 {{reference to type 'int' requires an initializer}}
// cxx98-note@#cwg304-m {{in value-initialization of type 'S' here}}
int m = S().b; // #cwg304-m
// since-cxx11-error@-1 {{call to implicitly-deleted default constructor of 'S'}}
// since-cxx11-note@#cwg304-S {{default constructor of 'S' is implicitly deleted because field 'b' of reference type 'int &' would not be initialized}}
}
namespace cwg305 { // cwg305: no
struct A {
typedef A C;
};
void f(A *a) {
struct A {};
a->~A();
a->~C();
}
typedef A B;
void g(B *b) {
b->~B();
b->~C();
}
void h(B *b) {
struct B {}; // #cwg305-h-B
b->~B();
// expected-error@-1 {{destructor type 'B' in object destruction expression does not match the type 'B' (aka 'cwg305::A') of the object being destroyed}}
// expected-note@#cwg305-h-B {{type 'B' found by destructor name lookup}}
}
template<typename T> struct X {};
void i(X<int>* x) {
struct X {};
x->~X<int>();
x->~X();
x->~X<char>();
// expected-error@-1 {{no member named '~X' in 'cwg305::X<int>'}}
}
#if __cplusplus >= 201103L
struct Y {
template<typename T> using T1 = Y;
};
template<typename T> using T2 = Y;
void j(Y *y) {
y->~T1<int>();
y->~T2<int>();
}
struct Z {
template<typename T> using T2 = T;
};
void k(Z *z) {
z->~T1<int>();
// expected-error@-1 {{no member named 'T1' in 'cwg305::Z'}}
z->~T2<int>();
// expected-error@-1 {{no member named '~int' in 'cwg305::Z'}}
z->~T2<Z>();
}
// FIXME: This is valid.
namespace Q {
template<typename A> struct R {};
}
template<typename A> using R = Q::R<int>;
void qr(Q::R<int> x) { x.~R<char>(); }
// expected-error@-1 {{no member named '~R' in 'cwg305::Q::R<int>'}}
#endif
}
namespace cwg306 { // cwg306: dup 39
struct A { struct B {}; };
struct C { typedef A::B B; };
struct D : A, A::B, C {};
D::B b;
struct X {}; // #cwg306-X
template<typename T> struct Y { typedef T X; }; // #cwg306-typedef-X
template<typename T> struct Z : X, Y<T> {};
Z<X>::X zx;
Z<const X>::X zcx;
// expected-error@-1 {{member 'X' found in multiple base classes of different types}}
// expected-note@#cwg306-X {{member type 'cwg306::X' found}}
// expected-note@#cwg306-typedef-X {{member type 'const cwg306::X' found}}
}
// cwg307: na
namespace cwg308 { // cwg308: 3.7
// This is mostly an ABI library issue.
struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {};
void f() {
// NB: the warning here is correct despite being the opposite of the
// comments in the catch handlers. The "unreachable" comment is correct
// because there is an ambiguous base path to A from the D that is thrown.
// The warnings generated are also correct because the handlers handle
// const B& and const A& and we don't check to see if other derived classes
// exist that would cause an ambiguous base path. We issue the diagnostic
// despite the potential for a false positive because users are not
// expected to have ambiguous base paths all that often, so the false
// positive rate should be acceptably low.
try {
throw D();
} catch (const A&) { // #cwg308-catch-A
// unreachable
} catch (const B&) {
// expected-warning@-1 {{exception of type 'const B &' will be caught by earlier handler}}
// expected-note@#cwg308-catch-A {{for type 'const A &'}}
// get here instead
}
}
}
// cwg309: dup 485
namespace cwg311 { // cwg311: 3.0
namespace X { namespace Y {} }
namespace X::Y {}
// cxx98-14-error@-1 {{nested namespace definition is a C++17 extension; define each namespace separately}}
namespace X {
namespace X::Y {}
// cxx98-14-error@-1 {{nested namespace definition is a C++17 extension; define each namespace separately}}
}
// FIXME: The diagnostics here are not very good.
namespace ::cwg311::X {}
// expected-error@-1 {{expected identifier or '{'}}
// expected-warning@-2 {{extra qualification on member 'X'}}
// expected-error@-3 {{a type specifier is required for all declarations}}
// expected-error@-4 {{expected ';' after top level declarator}}
}
// cwg312: dup 616
namespace cwg313 { // cwg313: dup 299 c++11
struct A { operator int() const; };
// FIXME: should this be available in c++98 mode?
int *p = new int[A()];
// cxx98-error@-1 {{implicit conversion from array size expression of type 'A' to integral type 'int' is a C++11 extension}}
}
namespace cwg314 { // cwg314: no
// NB: dup 1710
template <typename T> struct A {
template <typename U> struct B {};
};
template <typename T> struct C : public A<T>::template B<T> {
C() : A<T>::template B<T>() {}
};
template <typename T> struct C2 : public A<T>::B<T> {
// expected-error@-1 {{use 'template' keyword to treat 'B' as a dependent template name}}
C2() : A<T>::B<T>() {}
// expected-error@-1 {{use 'template' keyword to treat 'B' as a dependent template name}}
};
} // namespace cwg314
// cwg315: na
// cwg316: sup 1004
namespace cwg317 { // cwg317: 3.5
void f() {} // #cwg317-f
inline void f();
// expected-error@-1 {{inline declaration of 'f' follows non-inline definition}}
// expected-note@#cwg317-f {{previous definition is here}}
int g();
int n = g();
inline int g() { return 0; }
int h();
int m = h();
int h() { return 0; } // #cwg317-h
inline int h();
// expected-error@-1 {{inline declaration of 'h' follows non-inline definition}}
// expected-note@#cwg317-h {{previous definition is here}}
}
namespace cwg318 { // cwg318: sup 1310
struct A {};
struct A::A a;
}
namespace cwg319 { // cwg319: no
// FIXME: dup cwg389
// FIXME: We don't have a diagnostic for a name with linkage
// having a type without linkage.
typedef struct {
int i;
} *ps;
extern "C" void f(ps);
void g(ps); // FIXME: ill-formed, type 'ps' has no linkage
static enum { e } a1;
enum { e2 } a2; // FIXME: ill-formed, enum type has no linkage
enum { n1 = 1u };
typedef int (*pa)[n1];
pa parr; // ok, type has linkage despite using 'n1'
template<typename> struct X {};
void f() {
struct A { int n; };
extern A a; // FIXME: ill-formed
X<A> xa;
// cxx98-error@-1 {{template argument uses local type 'A'}}
typedef A B;
extern B b; // FIXME: ill-formed
X<B> xb;
// cxx98-error@-1 {{template argument uses local type 'A'}}
const int n = 1;
typedef int (*C)[n];
extern C c; // ok
X<C> xc;
}
}
namespace cwg320 { // cwg320: yes
#if __cplusplus >= 201103L
struct X {
constexpr X() {}
constexpr X(const X &x) : copies(x.copies + 1) {}
unsigned copies = 0;
};
constexpr X f(X x) { return x; }
constexpr unsigned g(X x) { return x.copies; }
static_assert(f(X()).copies == g(X()) + 1, "expected one extra copy for return value");
#endif
}
namespace cwg321 { // cwg321: dup 557
namespace N {
template<int> struct A {
template<int> struct B;
};
template<> template<> struct A<0>::B<0>;
void f(A<0>::B<0>);
}
template<> template<> struct N::A<0>::B<0> {};
template<typename T> void g(T t) { f(t); }
template void g(N::A<0>::B<0>);
namespace N {
template<typename> struct I { friend bool operator==(const I&, const I&); };
}
N::I<int> i, j;
bool x = i == j;
}
namespace cwg322 { // cwg322: 2.8
struct A {
template<typename T> operator T&();
} a;
int &r = static_cast<int&>(a);
int &s = a;
}
// cwg323: no
namespace cwg324 { // cwg324: 3.6
struct S { int n : 1; } s; // #cwg324-n
int &a = s.n;
// expected-error@-1 {{non-const reference cannot bind to bit-field 'n'}}
// expected-note@#cwg324-n {{bit-field is declared here}}
int *b = &s.n;
// expected-error@-1 {{address of bit-field requested}}
int &c = (s.n = 0);
// expected-error@-1 {{non-const reference cannot bind to bit-field 'n'}}
// expected-note@#cwg324-n {{bit-field is declared here}}
int *d = &(s.n = 0);
// expected-error@-1 {{address of bit-field requested}}
// FIXME: why don't we emit a note here, as for the rest of this type of diagnostic in this test?
int &e = true ? s.n : s.n;
// expected-error@-1 {{non-const reference cannot bind to bit-field}}
int *f = &(true ? s.n : s.n);
// expected-error@-1 {{address of bit-field requested}}
int &g = (void(), s.n);
// expected-error@-1 {{non-const reference cannot bind to bit-field 'n'}}
// expected-note@#cwg324-n {{bit-field is declared here}}
int *h = &(void(), s.n);
// expected-error@-1 {{address of bit-field requested}}
int *i = &++s.n;
// expected-error@-1 {{address of bit-field requested}}
}
namespace cwg326 { // cwg326: 3.1
struct S {};
int test[__is_trivially_constructible(S, const S&) ? 1 : -1];
}
namespace cwg327 { // cwg327: dup 538
struct A;
class A {};
class B;
struct B {};
}
namespace cwg328 { // cwg328: yes
struct A; // #cwg328-A
struct B { A a; };
// expected-error@-1 {{field has incomplete type 'A'}}
// expected-note@#cwg328-A {{forward declaration of 'cwg328::A'}}
template<typename> struct C { A a; };
// expected-error@-1 {{field has incomplete type 'A'}}
// expected-note@#cwg328-A {{forward declaration of 'cwg328::A'}}
A *p = new A[0];
// expected-error@-1 {{allocation of incomplete type 'A'}}
// expected-note@#cwg328-A {{forward declaration of 'cwg328::A'}}
}
namespace cwg329 { // cwg329: 3.5
struct B {};
template<typename T> struct A : B {
friend void f(A a) { g(a); }
friend void h(A a) { g(a); }
// expected-error@-1 {{use of undeclared identifier 'g'}}
// expected-note@#cwg329-h-call {{in instantiation of member function 'cwg329::h' requested here}}
friend void i(B b) {} // #cwg329-i
// expected-error@-1 {{redefinition of 'i'}}
// expected-note@#cwg329-b {{in instantiation of template class 'cwg329::A<char>' requested here}}
// expected-note@#cwg329-i {{previous definition is here}}
};
A<int> a;
A<char> b; // #cwg329-b
void test() {
h(a); // #cwg329-h-call
}
}
namespace cwg330 { // cwg330: 7
// Conversions between P and Q will be allowed by P0388.
typedef int *(*P)[3];
typedef const int *const (*Q)[3];
typedef const int *Qinner[3];
typedef Qinner const *Q2; // same as Q, but 'const' written outside the array type
typedef const int *const (*R)[4];
typedef const int *const (*S)[];
typedef const int *(*T)[];
void f(P p, Q q, Q2 q2, R r, S s, T t) {
q = p; // ok
q2 = p; // ok
r = p;
// expected-error@-1 {{incompatible pointer types assigning to 'R' (aka 'const int *const (*)[4]') from 'P' (aka 'int *(*)[3]')}}
s = p;
// cxx98-17-error@-1 {{incompatible pointer types assigning to 'S' (aka 'const int *const (*)[]') from 'P' (aka 'int *(*)[3]')}} (fixed by p0388)
t = p;
// expected-error@-1 {{incompatible pointer types assigning to 'T' (aka 'const int *(*)[]') from 'P' (aka 'int *(*)[3]')}}
s = q;
// cxx98-17-error@-1 {{incompatible pointer types assigning to 'S' (aka 'const int *const (*)[]') from 'Q' (aka 'const int *const (*)[3]')}} (fixed by p0388)
s = q2;
// cxx98-17-error@-1 {{incompatible pointer types assigning to 'S' (aka 'const int *const (*)[]') from 'Q2' (aka 'const int *const (*)[3]')}} (fixed by p0388)
s = t; // ok, adding const
t = s;
// expected-error@-1 {{assigning to 'T' (aka 'const int *(*)[]') from 'S' (aka 'const int *const (*)[]') discards qualifiers}}
(void) const_cast<P>(q);
(void) const_cast<P>(q2);
(void) const_cast<Q>(p);
(void) const_cast<Q2>(p);
(void) const_cast<S>(p);
// expected-error@-1 {{const_cast from 'P' (aka 'int *(*)[3]') to 'S' (aka 'const int *const (*)[]') is not allowed}} (for now)
(void) const_cast<P>(s);
// expected-error@-1 {{const_cast from 'S' (aka 'const int *const (*)[]') to 'P' (aka 'int *(*)[3]') is not allowed}} (for now)
(void) const_cast<S>(q);
// expected-error@-1 {{const_cast from 'Q' (aka 'const int *const (*)[3]') to 'S' (aka 'const int *const (*)[]') is not allowed}}
(void) const_cast<S>(q2);
// expected-error@-1 {{const_cast from 'Q2' (aka 'const int *const (*)[3]') to 'S' (aka 'const int *const (*)[]') is not allowed}}
(void) const_cast<Q>(s);
// expected-error@-1 {{const_cast from 'S' (aka 'const int *const (*)[]') to 'Q' (aka 'const int *const (*)[3]') is not allowed}}
(void) const_cast<Q2>(s);
// expected-error@-1 {{const_cast from 'S' (aka 'const int *const (*)[]') to 'Q2' (aka 'const int *const (*)[3]') is not allowed}}
(void) const_cast<T>(s);
(void) const_cast<S>(t);
(void) const_cast<T>(q);
// expected-error@-1 {{const_cast from 'Q' (aka 'const int *const (*)[3]') to 'T' (aka 'const int *(*)[]') is not allowed}}
(void) const_cast<Q>(t);
// expected-error@-1 {{const_cast from 'T' (aka 'const int *(*)[]') to 'Q' (aka 'const int *const (*)[3]') is not allowed}}
(void) reinterpret_cast<P>(q);
// expected-error@-1 {{reinterpret_cast from 'Q' (aka 'const int *const (*)[3]') to 'P' (aka 'int *(*)[3]') casts away qualifiers}}
(void) reinterpret_cast<P>(q2);
// expected-error@-1 {{reinterpret_cast from 'Q2' (aka 'const int *const (*)[3]') to 'P' (aka 'int *(*)[3]') casts away qualifiers}}
(void) reinterpret_cast<Q>(p);
(void) reinterpret_cast<Q2>(p);
(void) reinterpret_cast<S>(p);
(void) reinterpret_cast<P>(s);
// expected-error@-1 {{reinterpret_cast from 'S' (aka 'const int *const (*)[]') to 'P' (aka 'int *(*)[3]') casts away qualifiers}}
(void) reinterpret_cast<S>(q);
(void) reinterpret_cast<S>(q2);
(void) reinterpret_cast<Q>(s);
(void) reinterpret_cast<Q2>(s);
(void) reinterpret_cast<T>(s);
// expected-error@-1 {{reinterpret_cast from 'S' (aka 'const int *const (*)[]') to 'T' (aka 'const int *(*)[]') casts away qualifiers}}
(void) reinterpret_cast<S>(t);
(void) reinterpret_cast<T>(q);
// expected-error@-1 {{reinterpret_cast from 'Q' (aka 'const int *const (*)[3]') to 'T' (aka 'const int *(*)[]') casts away qualifiers}}
(void) reinterpret_cast<Q>(t);
}
namespace swift_17882 {
typedef const char P[72];
typedef int *Q;
void f(P &pr, P *pp) {
(void) reinterpret_cast<const Q&>(pr);
(void) reinterpret_cast<const Q*>(pp);
}
struct X {};
typedef const volatile int A[1][2][3];
typedef int *const X::*volatile *B1;
typedef int *const X::* *B2;
typedef int *X::* volatile *B3;
typedef volatile int *(*const B4)[4];
void f(A *a) {
(void) reinterpret_cast<B1*>(a);
(void) reinterpret_cast<B2*>(a);
// expected-error@-1 {{ISO C++ does not allow reinterpret_cast from 'A *' (aka 'const volatile int (*)[1][2][3]') to 'B2 *' (aka 'int *const cwg330::swift_17882::X::***') because it casts away qualifiers, even though the source and destination types are unrelated}}
(void) reinterpret_cast<B3*>(a);
// expected-error@-1 {{ISO C++ does not allow reinterpret_cast from 'A *' (aka 'const volatile int (*)[1][2][3]') to 'B3 *' (aka 'int *cwg330::swift_17882::X::*volatile **') because it casts away qualifiers, even though the source and destination types are unrelated}}
(void) reinterpret_cast<B4*>(a);
}
}
}
namespace cwg331 { // cwg331: 11
struct A {
A(volatile A&); // #cwg331-A-ctor
};
const A a;
// expected-error@-1 {{no matching constructor for initialization of 'const A'}}
// expected-note@#cwg331-A-ctor {{candidate constructor not viable: requires 1 argument, but 0 were provided}}
const A b(a);
// expected-error@-1 {{no matching constructor for initialization of 'const A'}}
// expected-note@#cwg331-A-ctor {{candidate constructor not viable: 1st argument ('const A') would lose const qualifier}}
}
namespace cwg332 { // cwg332: dup 577
void f(volatile void);
// expected-error@-1 {{'void' as parameter must not have type qualifiers}}
// cxx20-23-warning@-2 {{volatile-qualified parameter type 'volatile void' is deprecated}}
void g(const void);
// expected-error@-1 {{'void' as parameter must not have type qualifiers}}
void h(int n, volatile void);
// expected-error@-1 {{'void' must be the first and only parameter if specified}}
// cxx20-23-warning@-2 {{volatile-qualified parameter type 'volatile void' is deprecated}}
}
namespace cwg333 { // cwg333: yes
int n = 0;
int f(int(n));
int g((int(n)));
int h = f(g);
}
namespace cwg334 { // cwg334: yes
template<typename T> void f() {
T x;
f((x, 123));
}
struct S {
friend S operator,(S, int);
friend void f(S);
};
template void f<S>();
}
// cwg335: no
namespace cwg336 { // cwg336: yes
namespace Pre {
template<class T1> class A {
template<class T2> class B {
template<class T3> void mf1(T3);
void mf2();
};
};
template<> template<class X> class A<int>::B {};
template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {}
// expected-error@-1 {{out-of-line definition of 'mf1' does not match any declaration in 'cwg336::Pre::A<int>::B<double>'}}
template<class Y> template<> void A<Y>::B<double>::mf2() {}
// expected-error@-1 {{nested name specifier 'A<Y>::B<double>::' for declaration does not refer into a class, class template or class template partial specialization}}
}
namespace Post {
template<class T1> class A {
template<class T2> class B {
template<class T3> void mf1(T3);
void mf2();
};
};
template<> template<class X> class A<int>::B {
template<class T> void mf1(T);
};
template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {}
// FIXME: This diagnostic isn't very good.
template<class Y> template<> void A<Y>::B<double>::mf2() {}
// expected-error@-1 {{nested name specifier 'A<Y>::B<double>::' for declaration does not refer into a class, class template or class template partial specialization}}
}
}
namespace cwg337 { // cwg337: yes
template<typename T> void f(T (*)[1]);
template<typename T> int &f(...);
struct A { virtual ~A() = 0; };
int &r = f<A>(0);
// FIXME: The language rules here are completely broken. We cannot determine
// whether an incomplete type is abstract. See CWG1640, which will probably
// supersede this one and remove this rule.
struct B;
int &s = f<B>(0);
// expected-error@-1 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'void'}}
struct B { virtual ~B() = 0; };
}
namespace cwg339 { // cwg339: 2.8
template <int I> struct A { static const int value = I; };
char xxx(int);
char (&xxx(float))[2];
template<class T> A<sizeof(xxx((T)0))> f(T) {} // #cwg339-f
void test() {
A<1> a = f(0);
A<2> b = f(0.0f);
A<3> c = f("foo");
// expected-error@-1 {{no matching function}}
// expected-note@#cwg339-f {{candidate}}
}
char f(int);
int f(...);
template <class T> struct conv_int {
static const bool value = sizeof(f(T())) == 1;
};
template <class T> bool conv_int2(A<sizeof(f(T()))> p);
template<typename T> A<sizeof(f(T()))> make_A();
int a[conv_int<char>::value ? 1 : -1];
bool b = conv_int2<char>(A<1>());
A<1> c = make_A<char>();
}
namespace cwg340 { // cwg340: yes
struct A { A(int); };
struct B { B(A, A, int); };
int x, y;
B b(A(x), A(y), 3);
}
namespace cwg341 { // cwg341: sup 1708
namespace A {
int n;
extern "C" int &cwg341_a = n; // #cwg341_a
}
namespace B {
extern "C" int &cwg341_a = cwg341_a;
// expected-error@-1 {{redefinition of 'cwg341_a'}}
// expected-note@#cwg341_a {{previous definition is here}}
}
extern "C" void cwg341_b(); // #cwg341_b
}
int cwg341_a;
// expected-error@-1 {{declaration of 'cwg341_a' in global scope conflicts with declaration with C language linkage}}
// expected-note@#cwg341_a {{declared with C language linkage here}}
int cwg341_b;
// expected-error@-1 {{declaration of 'cwg341_b' in global scope conflicts with declaration with C language linkage}}
// expected-note@#cwg341_b {{declared with C language linkage here}}
int cwg341_c; // #cwg341_c
int cwg341_d; // #cwg341_d
namespace cwg341 {
extern "C" int cwg341_c;
// expected-error@-1 {{declaration of 'cwg341_c' with C language linkage conflicts with declaration in global scope}}
// expected-note@#cwg341_c {{declared in global scope here}}
extern "C" void cwg341_d();
// expected-error@-1 {{declaration of 'cwg341_d' with C language linkage conflicts with declaration in global scope}}
// expected-note@#cwg341_d {{declared in global scope here}}
namespace A { extern "C" int cwg341_e; } // #cwg341_e
namespace B { extern "C" void cwg341_e(); }
// expected-error@-1 {{redefinition of 'cwg341_e' as different kind of symbol}}
// expected-note@#cwg341_e {{previous definition is here}}
}
// cwg342: na
namespace cwg343 { // cwg343: no
// FIXME: dup 1710
template<typename T> struct A {
template<typename U> struct B {};
};
// FIXME: In these contexts, the 'template' keyword is optional.
template<typename T> struct C : public A<T>::B<T> {
// expected-error@-1 {{use 'template' keyword to treat 'B' as a dependent template name}}
C() : A<T>::B<T>() {}
// expected-error@-1 {{use 'template' keyword to treat 'B' as a dependent template name}}
};
}
namespace cwg344 { // cwg344: dup 1435
struct A { inline virtual ~A(); };
struct B { friend A::~A(); };
}
namespace cwg345 { // cwg345: yes
struct A {
struct X {};
int X; // #cwg345-int-X
};
struct B {
struct X {};
};
template <class T> void f(T t) { typename T::X x; }
// expected-error@-1 {{typename specifier refers to non-type member 'X' in 'cwg345::A'}}
// expected-note@#cwg345-f-a {{in instantiation of function template specialization 'cwg345::f<cwg345::A>' requested here}}
// expected-note@#cwg345-int-X {{referenced member 'X' is declared here}}
void f(A a, B b) {
f(b);
f(a); // #cwg345-f-a
}
}
// cwg346: na
namespace cwg347 { // cwg347: yes
struct base {
struct nested;
static int n;
static void f();
void g();
};
struct derived : base {};
struct derived::nested {};
// expected-error@-1 {{no struct named 'nested' in 'cwg347::derived'}}
int derived::n;
// expected-error@-1 {{no member named 'n' in 'cwg347::derived'}}
void derived::f() {}
// expected-error@-1 {{out-of-line definition of 'f' does not match any declaration in 'cwg347::derived'}}
void derived::g() {}
// expected-error@-1 {{out-of-line definition of 'g' does not match any declaration in 'cwg347::derived'}}
}
// cwg348: na
namespace cwg349 { // cwg349: no
struct A {
template <class T> operator T ***() {
int ***p = 0;
return p;
// cxx98-20-error@-1 {{cannot initialize return object of type 'const int ***' with an lvalue of type 'int ***'}}
// since-cxx23-error@-2 {{cannot initialize return object of type 'const int ***' with an rvalue of type 'int ***'}}
// expected-note@#cwg349-p1 {{in instantiation of function template specialization 'cwg349::A::operator const int ***<const int>' requested here}}
}
};
// FIXME: This is valid.
A a;
const int *const *const *p1 = a; // #cwg349-p1
struct B {
template <class T> operator T ***() {
const int ***p = 0;
return p;
}
};
// FIXME: This is invalid.
B b;
const int *const *const *p2 = b;
}
// cwg351: na
namespace cwg352 { // cwg352: 2.8
namespace example1 {
namespace A {
enum E {};
template<typename R, typename A> void foo(E, R (*)(A)); // #cwg352-foo
}
template<typename T> void arg(T);
template<typename T> int arg(T) = delete; // #cwg352-deleted
// cxx98-error@-1 {{deleted function definitions are a C++11 extension}}
void f(A::E e) {
foo(e, &arg);
// expected-error@-1 {{no matching function for call to 'foo'}}
// expected-note@#cwg352-foo {{candidate template ignored: couldn't infer template argument 'R'}}
using A::foo;
foo<int, int>(e, &arg);
// expected-error@-1 {{attempt to use a deleted function}}
// expected-note@#cwg352-deleted {{'arg<int>' has been explicitly marked deleted here}}
}
int arg(int);
void g(A::E e) {
foo(e, &arg);
// expected-error@-1 {{no matching function for call to 'foo'}}
// expected-note@#cwg352-foo {{candidate template ignored: couldn't infer template argument 'R'}}
using A::foo;
foo<int, int>(e, &arg); // ok, uses non-template
}
}
namespace contexts {
template<int I> void f1(int (&)[I]);
template<int I> void f2(int (&)[I+1]); // #cwg352-f2
template<int I> void f3(int (&)[I+1], int (&)[I]);
void f() {
int a[4];
int b[3];
f1(a);
f2(a);
// expected-error@-1 {{no matching function for call to 'f2'}}
// expected-note@#cwg352-f2 {{candidate template ignored: couldn't infer template argument 'I'}}
f3(a, b);
}
template<int I> struct S {};
template<int I> void g1(S<I>);
template<int I> void g2(S<I+1>); // #cwg352-g2
template<int I> void g3(S<I+1>, S<I>);
void g() {
S<4> a;
S<3> b;
g1(a);
g2(a);
// expected-error@-1 {{no matching function for call to 'g2'}}
// expected-note@#cwg352-g2 {{candidate template ignored: couldn't infer template argument 'I'}}
g3(a, b);
}
template<typename T> void h1(T = 0); // #cwg352-h1
template<typename T> void h2(T, T = 0);
void h() {
h1();
// expected-error@-1 {{no matching function for call to 'h1'}}
// expected-note@#cwg352-h1 {{candidate template ignored: couldn't infer template argument 'T'}}
h1(0);
h1<int>();
h2(0);
}
template<typename T> int tmpl(T);
template<typename R, typename A> void i1(R (*)(A)); // #cwg352-i1
template<typename R, typename A> void i2(R, A, R (*)(A)); // #cwg352-i2
void i() {
extern int single(int);
i1(single);
i2(0, 0, single);
extern int ambig(float), ambig(int);
i1(ambig);
// expected-error@-1 {{no matching function for call to 'i1'}}
// expected-note@#cwg352-i1 {{candidate template ignored: couldn't infer template argument 'R'}}
i2(0, 0, ambig);
extern void no_match(float), no_match(int);
i1(no_match);
// expected-error@-1 {{no matching function for call to 'i1'}}
// expected-note@#cwg352-i1 {{candidate template ignored: couldn't infer template argument 'R'}}
i2(0, 0, no_match);
// expected-error@-1 {{no matching function for call to 'i2'}}
// expected-note@#cwg352-i2 {{candidate function [with R = int, A = int] not viable: no overload of 'no_match' matching 'int (*)(int)' for 3rd argument}}
i1(tmpl);
// expected-error@-1 {{no matching function for call to 'i1'}}
// expected-note@#cwg352-i1 {{candidate template ignored: couldn't infer template argument 'R'}}
i2(0, 0, tmpl);
}
}
template<typename T> struct is_int;
template<> struct is_int<int> {};
namespace example2 {
template<typename T> int f(T (*p)(T)) { is_int<T>(); }
int g(int);
int g(char);
int i = f(g);
}
namespace example3 {
template<typename T> int f(T, T (*p)(T)) { is_int<T>(); }
int g(int);
char g(char);
int i = f(1, g);
}
namespace example4 {
template <class T> int f(T, T (*p)(T)) { is_int<T>(); }
char g(char);
template <class T> T g(T);
int i = f(1, g);
}
namespace example5 {
template<int I> class A {};
template<int I> void g(A<I+1>); // #cwg352-g
template<int I> void f(A<I>, A<I+1>);
void h(A<1> a1, A<2> a2) {
g(a1);
// expected-error@-1 {{no matching function for call to 'g'}}
// expected-note@#cwg352-g {{candidate template ignored: couldn't infer template argument 'I'}}
g<0>(a1);
f(a1, a2);
}
}
}
// cwg353 needs an IRGen test.
namespace cwg354 { // cwg354: yes c++11
// FIXME: Should we allow this in C++98 too?
struct S {};
template<int*> struct ptr {}; // #cwg354-ptr
ptr<0> p0; // #cwg354-p0
// cxx98-error@#cwg354-p0 {{non-type template argument does not refer to any declaration}}
// cxx98-note@#cwg354-ptr {{template parameter is declared here}}
// cxx11-14-error@#cwg354-p0 {{null non-type template argument must be cast to template parameter type 'int *'}}
// cxx11-14-note@#cwg354-ptr {{template parameter is declared here}}
// since-cxx17-error@#cwg354-p0 {{conversion from 'int' to 'int *' is not allowed in a converted constant expression}}
ptr<(int*)0> p1;
// cxx98-error@-1 {{non-type template argument does not refer to any declaration}}
// cxx98-note@#cwg354-ptr {{template parameter is declared here}}
ptr<(float*)0> p2; // #cwg354-p2
// cxx98-error@#cwg354-p2 {{non-type template argument does not refer to any declaration}}
// cxx98-note@#cwg354-ptr {{template parameter is declared here}}
// cxx11-14-error@#cwg354-p2 {{null non-type template argument of type 'float *' does not match template parameter of type 'int *'}}
// cxx11-14-note@#cwg354-ptr {{template parameter is declared here}}
// since-cxx17-error@#cwg354-p2 {{value of type 'float *' is not implicitly convertible to 'int *'}}
ptr<(int S::*)0> p3; // #cwg354-p3
// cxx98-error@#cwg354-p3 {{non-type template argument does not refer to any declaration}}
// cxx98-note@#cwg354-ptr {{template parameter is declared here}}
// cxx11-14-error@#cwg354-p3 {{null non-type template argument of type 'int cwg354::S::*' does not match template parameter of type 'int *'}}
// cxx11-14-note@#cwg354-ptr {{template parameter is declared here}}
// since-cxx17-error@#cwg354-p3 {{value of type 'int cwg354::S::*' is not implicitly convertible to 'int *'}}
template<int*> int both(); // #cwg354-both-int-ptr
template<int> int both(); // #cwg354-both-int
int b0 = both<0>();
int b1 = both<(int*)0>();
// cxx98-error@-1 {{no matching function for call to 'both'}}
// cxx98-note@#cwg354-both-int-ptr {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
// cxx98-note@#cwg354-both-int {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
template<int S::*> struct ptr_mem {}; // #cwg354-ptr_mem
ptr_mem<0> m0; // #cwg354-m0
// cxx98-error@#cwg354-m0 {{non-type template argument of type 'int' cannot be converted to a value of type 'int cwg354::S::*'}}
// cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}}
// cxx11-14-error@#cwg354-m0 {{null non-type template argument must be cast to template parameter type 'int cwg354::S::*'}}
// cxx11-14-note@#cwg354-ptr_mem {{template parameter is declared here}}
// since-cxx17-error@#cwg354-m0 {{conversion from 'int' to 'int cwg354::S::*' is not allowed in a converted constant expression}}
ptr_mem<(int S::*)0> m1;
// cxx98-error@-1 {{non-type template argument is not a pointer to member constant}}
ptr_mem<(float S::*)0> m2; // #cwg354-m2
// cxx98-error@#cwg354-m2 {{non-type template argument of type 'float cwg354::S::*' cannot be converted to a value of type 'int cwg354::S::*'}}
// cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}}
// cxx11-14-error@#cwg354-m2 {{null non-type template argument of type 'float cwg354::S::*' does not match template parameter of type 'int cwg354::S::*'}}
// cxx11-14-note@#cwg354-ptr_mem {{template parameter is declared here}}
// since-cxx17-error@#cwg354-m2 {{value of type 'float cwg354::S::*' is not implicitly convertible to 'int cwg354::S::*'}}
ptr_mem<(int *)0> m3; // #cwg354-m3
// cxx98-error@#cwg354-m3 {{non-type template argument of type 'int *' cannot be converted to a value of type 'int cwg354::S::*'}}
// cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}}
// cxx11-14-error@#cwg354-m3 {{null non-type template argument of type 'int *' does not match template parameter of type 'int cwg354::S::*'}}
// cxx11-14-note@#cwg354-ptr_mem {{template parameter is declared here}}
// since-cxx17-error@#cwg354-m3 {{value of type 'int *' is not implicitly convertible to 'int cwg354::S::*'}}
}
struct cwg355_S; // cwg355: yes
struct ::cwg355_S {};
// expected-warning@-1 {{extra qualification on member 'cwg355_S'}}
namespace cwg355 { struct ::cwg355_S s; }
// cwg356: na
namespace cwg357 { // cwg357: yes