dr2xx.cpp revision e3a404411fe651097024edece9a72afeef5f6ac3
1// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
2// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
3// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
4
5#if __cplusplus < 201103L
6#define fold(x) (__builtin_constant_p(x) ? (x) : (x))
7#else
8#define fold
9#endif
10
11namespace dr200 { // dr200: dup 214
12  template <class T> T f(int);
13  template <class T, class U> T f(U) = delete; // expected-error 0-1{{extension}}
14
15  void g() {
16    f<int>(1);
17  }
18}
19
20// dr201 FIXME: write codegen test
21
22namespace dr202 { // dr202: yes
23  template<typename T> T f();
24  template<int (*g)()> struct X {
25    int arr[fold(g == &f<int>) ? 1 : -1];
26  };
27  template struct X<f>;
28}
29
30// FIXME (export) dr204: no
31
32namespace dr206 { // dr206: yes
33  struct S; // expected-note 2{{declaration}}
34  template<typename T> struct Q { S s; }; // expected-error {{incomplete}}
35  template<typename T> void f() { S s; } // expected-error {{incomplete}}
36}
37
38namespace dr207 { // dr207: yes
39  class A {
40  protected:
41    static void f() {}
42  };
43  class B : A {
44  public:
45    using A::f;
46    void g() {
47      A::f();
48      f();
49    }
50  };
51}
52
53// dr208 FIXME: write codegen test
54
55namespace dr209 { // dr209: yes
56  class A {
57    void f(); // expected-note {{here}}
58  };
59  class B {
60    friend void A::f(); // expected-error {{private}}
61  };
62}
63
64// dr210 FIXME: write codegen test
65
66namespace dr211 { // dr211: yes
67  struct A {
68    A() try {
69      throw 0;
70    } catch (...) {
71      return; // expected-error {{return in the catch of a function try block of a constructor}}
72    }
73  };
74}
75
76namespace dr213 { // dr213: yes
77  template <class T> struct A : T {
78    void h(T t) {
79      char &r1 = f(t);
80      int &r2 = g(t); // expected-error {{undeclared}}
81    }
82  };
83  struct B {
84    int &f(B);
85    int &g(B); // expected-note {{in dependent base class}}
86  };
87  char &f(B);
88
89  template void A<B>::h(B); // expected-note {{instantiation}}
90}
91
92namespace dr214 { // dr214: yes
93  template<typename T, typename U> T checked_cast(U from) { U::error; }
94  template<typename T, typename U> T checked_cast(U *from);
95  class C {};
96  void foo(int *arg) { checked_cast<const C *>(arg); }
97
98  template<typename T> T f(int);
99  template<typename T, typename U> T f(U) { T::error; }
100  void g() {
101    f<int>(1);
102  }
103}
104
105namespace dr215 { // dr215: yes
106  template<typename T> class X {
107    friend void T::foo();
108    int n;
109  };
110  struct Y {
111    void foo() { (void)+X<Y>().n; }
112  };
113}
114
115namespace dr216 { // dr216: no
116  // FIXME: Should reject this: 'f' has linkage but its type does not,
117  // and 'f' is odr-used but not defined in this TU.
118  typedef enum { e } *E;
119  void f(E);
120  void g(E e) { f(e); }
121
122  struct S {
123    // FIXME: Should reject this: 'f' has linkage but its type does not,
124    // and 'f' is odr-used but not defined in this TU.
125    typedef enum { e } *E;
126    void f(E);
127  };
128  void g(S s, S::E e) { s.f(e); }
129}
130
131namespace dr217 { // dr217: yes
132  template<typename T> struct S {
133    void f(int);
134  };
135  template<typename T> void S<T>::f(int = 0) {} // expected-error {{default arguments cannot be added}}
136}
137
138namespace dr218 { // dr218: yes
139  namespace A {
140    struct S {};
141    void f(S);
142  }
143  namespace B {
144    struct S {};
145    void f(S);
146  }
147
148  struct C {
149    int f;
150    void test1(A::S as) { f(as); } // expected-error {{called object type 'int'}}
151    void test2(A::S as) { void f(); f(as); } // expected-error {{too many arguments}} expected-note {{}}
152    void test3(A::S as) { using A::f; f(as); } // ok
153    void test4(A::S as) { using B::f; f(as); } // ok
154    void test5(A::S as) { int f; f(as); } // expected-error {{called object type 'int'}}
155    void test6(A::S as) { struct f {}; (void) f(as); } // expected-error {{no matching conversion}} expected-note +{{}}
156  };
157
158  namespace D {
159    struct S {};
160    struct X { void operator()(S); } f;
161  }
162  void testD(D::S ds) { f(ds); } // expected-error {{undeclared identifier}}
163
164  namespace E {
165    struct S {};
166    struct f { f(S); };
167  }
168  void testE(E::S es) { f(es); } // expected-error {{undeclared identifier}}
169
170  namespace F {
171    struct S {
172      template<typename T> friend void f(S, T) {}
173    };
174  }
175  void testF(F::S fs) { f(fs, 0); }
176
177  namespace G {
178    namespace X {
179      int f;
180      struct A {};
181    }
182    namespace Y {
183      template<typename T> void f(T);
184      struct B {};
185    }
186    template<typename A, typename B> struct C {};
187  }
188  void testG(G::C<G::X::A, G::Y::B> gc) { f(gc); }
189}
190
191// dr219: na
192// dr220: na
193
194namespace dr221 { // dr221: yes
195  struct A {
196    A &operator=(int&);
197    A &operator+=(int&);
198    static A &operator=(A&, double&); // expected-error {{cannot be a static member}}
199    static A &operator+=(A&, double&); // expected-error {{cannot be a static member}}
200    friend A &operator=(A&, char&); // expected-error {{must be a non-static member function}}
201    friend A &operator+=(A&, char&);
202  };
203  A &operator=(A&, float&); // expected-error {{must be a non-static member function}}
204  A &operator+=(A&, float&);
205
206  void test(A a, int n, char c, float f) {
207    a = n;
208    a += n;
209    a = c;
210    a += c;
211    a = f;
212    a += f;
213  }
214}
215
216// dr222 is a mystery -- it lists no changes to the standard, and yet was
217// apparently both voted into the WP and acted upon by the editor.
218
219// dr223: na
220
221namespace dr224 { // dr224: no
222  namespace example1 {
223    template <class T> class A {
224      typedef int type;
225      A::type a;
226      A<T>::type b;
227      A<T*>::type c; // expected-error {{missing 'typename'}}
228      ::dr224::example1::A<T>::type d;
229
230      class B {
231        typedef int type;
232
233        A::type a;
234        A<T>::type b;
235        A<T*>::type c; // expected-error {{missing 'typename'}}
236        ::dr224::example1::A<T>::type d;
237
238        B::type e;
239        A<T>::B::type f;
240        A<T*>::B::type g; // expected-error {{missing 'typename'}}
241        typename A<T*>::B::type h;
242      };
243    };
244
245    template <class T> class A<T*> {
246      typedef int type;
247      A<T*>::type a;
248      A<T>::type b; // expected-error {{missing 'typename'}}
249    };
250
251    template <class T1, class T2, int I> struct B {
252      typedef int type;
253      B<T1, T2, I>::type b1;
254      B<T2, T1, I>::type b2; // expected-error {{missing 'typename'}}
255
256      typedef T1 my_T1;
257      static const int my_I = I;
258      static const int my_I2 = I+0;
259      static const int my_I3 = my_I;
260      B<my_T1, T2, my_I>::type b3; // FIXME: expected-error {{missing 'typename'}}
261      B<my_T1, T2, my_I2>::type b4; // expected-error {{missing 'typename'}}
262      B<my_T1, T2, my_I3>::type b5; // FIXME: expected-error {{missing 'typename'}}
263    };
264  }
265
266  namespace example2 {
267    template <int, typename T> struct X { typedef T type; };
268    template <class T> class A {
269      static const int i = 5;
270      X<i, int>::type w; // FIXME: expected-error {{missing 'typename'}}
271      X<A::i, char>::type x; // FIXME: expected-error {{missing 'typename'}}
272      X<A<T>::i, double>::type y; // FIXME: expected-error {{missing 'typename'}}
273      X<A<T*>::i, long>::type z; // expected-error {{missing 'typename'}}
274      int f();
275    };
276    template <class T> int A<T>::f() {
277      return i;
278    }
279  }
280}
281
282// dr225: yes
283template<typename T> void dr225_f(T t) { dr225_g(t); } // expected-error {{call to function 'dr225_g' that is neither visible in the template definition nor found by argument-dependent lookup}}
284void dr225_g(int); // expected-note {{should be declared prior to the call site}}
285template void dr225_f(int); // expected-note {{in instantiation of}}
286
287namespace dr226 { // dr226: no
288  template<typename T = void> void f() {}
289#if __cplusplus < 201103L
290  // expected-error@-2 {{extension}}
291  // FIXME: This appears to be wrong: default arguments for function templates
292  // are listed as a defect (in c++98) not an extension. EDG accepts them in
293  // strict c++98 mode.
294#endif
295  template<typename T> struct S {
296    template<typename U = void> void g();
297#if __cplusplus < 201103L
298  // expected-error@-2 {{extension}}
299#endif
300    template<typename U> struct X;
301    template<typename U> void h();
302  };
303  template<typename T> template<typename U> void S<T>::g() {}
304  template<typename T> template<typename U = void> struct S<T>::X {}; // expected-error {{cannot add a default template arg}}
305  template<typename T> template<typename U = void> void S<T>::h() {} // expected-error {{cannot add a default template arg}}
306
307  template<typename> void friend_h();
308  struct A {
309    // FIXME: This is ill-formed.
310    template<typename=void> struct friend_B;
311    // FIXME: f, h, and i are ill-formed.
312    //  f is ill-formed because it is not a definition.
313    //  h and i are ill-formed because they are not the only declarations of the
314    //  function in the translation unit.
315    template<typename=void> void friend_f();
316    template<typename=void> void friend_g() {}
317    template<typename=void> void friend_h() {}
318    template<typename=void> void friend_i() {}
319#if __cplusplus < 201103L
320  // expected-error@-5 {{extension}} expected-error@-4 {{extension}}
321  // expected-error@-4 {{extension}} expected-error@-3 {{extension}}
322#endif
323  };
324  template<typename> void friend_i();
325
326  template<typename=void, typename X> void foo(X) {}
327  template<typename=void, typename X> struct Foo {}; // expected-error {{missing a default argument}} expected-note {{here}}
328#if __cplusplus < 201103L
329  // expected-error@-3 {{extension}}
330#endif
331
332  template<typename=void, typename X, typename, typename Y> int foo(X, Y);
333  template<typename, typename X, typename=void, typename Y> int foo(X, Y);
334  int x = foo(0, 0);
335#if __cplusplus < 201103L
336  // expected-error@-4 {{extension}}
337  // expected-error@-4 {{extension}}
338#endif
339}
340
341void dr227(bool b) { // dr227: yes
342  if (b)
343    int n;
344  else
345    int n;
346}
347
348namespace dr228 { // dr228: yes
349  template <class T> struct X {
350    void f();
351  };
352  template <class T> struct Y {
353    void g(X<T> x) { x.template X<T>::f(); }
354  };
355}
356
357namespace dr229 { // dr229: yes
358  template<typename T> void f();
359  template<typename T> void f<T*>() {} // expected-error {{function template partial specialization}}
360  template<> void f<int>() {}
361}
362
363namespace dr231 { // dr231: yes
364  namespace outer {
365    namespace inner {
366      int i; // expected-note {{here}}
367    }
368    void f() { using namespace inner; }
369    int j = i; // expected-error {{undeclared identifier 'i'; did you mean 'inner::i'?}}
370  }
371}
372
373// dr234: na
374// dr235: na
375
376namespace dr236 { // dr236: yes
377  void *p = int();
378#if __cplusplus < 201103L
379  // expected-warning@-2 {{null pointer}}
380#else
381  // expected-error@-4 {{cannot initialize}}
382#endif
383}
384
385namespace dr237 { // dr237: dup 470
386  template<typename T> struct A { void f() { T::error; } };
387  template<typename T> struct B : A<T> {};
388  template struct B<int>; // ok
389}
390
391namespace dr239 { // dr239: yes
392  namespace NS {
393    class T {};
394    void f(T);
395    float &g(T, int);
396  }
397  NS::T parm;
398  int &g(NS::T, float);
399  int main() {
400    f(parm);
401    float &r = g(parm, 1);
402    extern int &g(NS::T, float);
403    int &s = g(parm, 1);
404  }
405}
406
407// dr240: dup 616
408
409namespace dr241 { // dr241: yes
410  namespace A {
411    struct B {};
412    template <int X> void f(); // expected-note 2{{candidate}}
413    template <int X> void g(B);
414  }
415  namespace C {
416    template <class T> void f(T t); // expected-note 2{{candidate}}
417    template <class T> void g(T t); // expected-note {{candidate}}
418  }
419  void h(A::B b) {
420    f<3>(b); // expected-error {{undeclared identifier}}
421    g<3>(b); // expected-error {{undeclared identifier}}
422    A::f<3>(b); // expected-error {{no matching}}
423    A::g<3>(b);
424    C::f<3>(b); // expected-error {{no matching}}
425    C::g<3>(b); // expected-error {{no matching}}
426    using C::f;
427    using C::g;
428    f<3>(b); // expected-error {{no matching}}
429    g<3>(b);
430  }
431}
432
433namespace dr243 { // dr243: yes
434  struct B;
435  struct A {
436    A(B); // expected-note {{candidate}}
437  };
438  struct B {
439    operator A() = delete; // expected-error 0-1{{extension}} expected-note {{candidate}}
440  } b;
441  A a1(b);
442  A a2 = b; // expected-error {{ambiguous}}
443}
444
445namespace dr244 { // dr244: no
446  struct B {}; struct D : B {}; // expected-note {{here}}
447
448  D D_object;
449  typedef B B_alias;
450  B* B_ptr = &D_object;
451
452  void f() {
453    D_object.~B(); // expected-error {{expression does not match the type}}
454    D_object.B::~B();
455    B_ptr->~B();
456    B_ptr->~B_alias();
457    B_ptr->B_alias::~B();
458    // This is valid under DR244.
459    B_ptr->B_alias::~B_alias(); // FIXME: expected-error {{expected the class name after '~' to name a destructor}}
460    B_ptr->dr244::~B(); // expected-error {{refers to a member in namespace}}
461    B_ptr->dr244::~B_alias(); // expected-error {{refers to a member in namespace}}
462  }
463}
464
465namespace dr245 { // dr245: yes
466  struct S {
467    enum E {}; // expected-note {{here}}
468    class E *p; // expected-error {{does not match previous declaration}}
469  };
470}
471
472namespace dr246 { // dr246: yes
473  struct S {
474    S() try { // expected-note {{try block}}
475      throw 0;
476X: ;
477    } catch (int) {
478      goto X; // expected-error {{protected scope}}
479    }
480  };
481}
482
483namespace dr247 { // dr247: yes
484  struct A {};
485  struct B : A {
486    void f();
487    void f(int);
488  };
489  void (A::*f)() = (void (A::*)())&B::f;
490
491  struct C {
492    void f();
493    void f(int);
494  };
495  struct D : C {};
496  void (C::*g)() = &D::f;
497  void (D::*h)() = &D::f;
498
499  struct E {
500    void f();
501  };
502  struct F : E {
503    using E::f;
504    void f(int);
505  };
506  void (F::*i)() = &F::f;
507}
508
509namespace dr248 { // dr248: yes c++11
510  // FIXME: Should this also apply to c++98 mode? This was a DR against C++98.
511  int \u040d\u040e = 0;
512#if __cplusplus < 201103L
513  // FIXME: expected-error@-2 {{expected ';'}}
514#endif
515}
516
517namespace dr249 { // dr249: yes
518  template<typename T> struct X { void f(); };
519  template<typename T> void X<T>::f() {}
520}
521
522namespace dr250 { // dr250: yes
523  typedef void (*FPtr)(double x[]);
524
525  template<int I> void f(double x[]);
526  FPtr fp = &f<3>;
527
528  template<int I = 3> void g(double x[]); // expected-error 0-1{{extension}}
529  FPtr gp = &g<>;
530}
531