dr5xx.cpp revision 6bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89
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
5namespace dr500 { // dr500: dup 372
6  class D;
7  class A {
8    class B;
9    class C;
10    friend class D;
11  };
12  class A::B {};
13  class A::C : public A::B {};
14  class D : public A::B {};
15}
16
17namespace dr501 { // dr501: yes
18  struct A {
19    friend void f() {}
20    void g() {
21      void (*p)() = &f; // expected-error {{undeclared identifier}}
22    }
23  };
24}
25
26namespace dr502 { // dr502: yes
27  struct Q {};
28  template<typename T> struct A {
29    enum E { e = 1 };
30    void q1() { f(e); }
31    void q2() { Q arr[sizeof(E)]; f(arr); }
32    void q3() { Q arr[e]; f(arr); }
33    void sanity() { Q arr[1]; f(arr); } // expected-error {{undeclared identifier 'f'}}
34  };
35  int f(A<int>::E);
36  template<int N> int f(Q (&)[N]);
37  template struct A<int>;
38}
39
40namespace dr505 { // dr505: yes
41  const char *exts = "\e\(\{\[\%"; // expected-error 5{{use of non-standard escape}}
42  const char *unknown = "\Q"; // expected-error {{unknown escape sequence}}
43}
44
45namespace dr506 { // dr506: yes
46  struct NonPod { ~NonPod(); };
47  void f(...);
48  void g(NonPod np) { f(np); } // expected-error {{cannot pass}}
49}
50
51// FIXME: Add tests here once DR260 is resolved.
52// dr507: dup 260
53
54// dr508: na
55// dr509: na
56// dr510: na
57
58namespace dr512 { // dr512: yes
59  struct A {
60    A(int);
61  };
62  union U { A a; };
63#if __cplusplus < 201103L
64  // expected-error@-2 {{has a non-trivial constructor}}
65  // expected-note@-6 {{no default constructor}}
66  // expected-note@-6 {{suppressed by user-declared constructor}}
67#endif
68}
69
70// dr513: na
71
72namespace dr514 { // dr514: yes
73  namespace A { extern int x, y; }
74  int A::x = y;
75}
76
77namespace dr515 { // dr515: sup 1017
78  // FIXME: dr1017 reverses the wording of dr515, but the current draft has
79  // dr515's wording, with a different fix for dr1017.
80
81  struct X { int n; };
82  template<typename T> struct Y : T {
83    int f() { return X::n; }
84  };
85  int k = Y<X>().f();
86
87  struct A { int a; };
88  struct B { void f() { int k = sizeof(A::a); } };
89#if __cplusplus < 201103L
90  // expected-error@-2 {{invalid use of non-static data member}}
91#endif
92}
93
94// dr516: na
95
96namespace dr517 { // dr517: no
97  // This is NDR, but we should diagnose it anyway.
98  template<typename T> struct S {};
99  template<typename T> int v = 0; // expected-error 0-1{{extension}}
100
101  template struct S<int*>;
102  template int v<int*>;
103
104  S<char&> s;
105  int k = v<char&>;
106
107  // FIXME: These are both ill-formed.
108  template<typename T> struct S<T*> {};
109  template<typename T> int v<T*> = 0; // expected-error 0-1{{extension}}
110
111  // FIXME: These are both ill-formed.
112  template<typename T> struct S<T&> {};
113  template<typename T> int v<T&> = 0; // expected-error 0-1{{extension}}
114}
115
116namespace dr518 { // dr518: yes c++11
117  enum E { e, };
118#if __cplusplus < 201103L
119  // expected-error@-2 {{C++11 extension}}
120#endif
121}
122
123namespace dr519 { // dr519: yes
124// FIXME: Add a codegen test.
125#if __cplusplus >= 201103L
126#define fold(x) (__builtin_constant_p(x) ? (x) : (x))
127  int test[fold((int*)(void*)0) ? -1 : 1];
128#undef fold
129#endif
130}
131
132// dr520: na
133
134// dr521: no
135// FIXME: The wording here is broken. It's not reasonable to expect a
136// diagnostic here. Once the relevant DR gets a number, mark this as a dup.
137
138namespace dr522 { // dr522: yes
139  struct S {};
140  template<typename T> void b1(volatile T &);
141  template<typename T> void b2(volatile T * const *);
142  template<typename T> void b2(volatile T * const S::*);
143  template<typename T> void b2(volatile T * const S::* const *);
144  // FIXME: This diagnostic isn't very good. The problem is not substitution failure.
145  template<typename T> void b2a(volatile T *S::* const *); // expected-note {{substitution failure}}
146
147  template<typename T> struct Base {};
148  struct Derived : Base<int> {};
149  template<typename T> void b3(Base<T>);
150  template<typename T> void b3(Base<T> *);
151
152  void test(int n, const int cn, int **p, int *S::*pm) {
153    int *a[3], *S::*am[3];
154    const Derived cd = Derived();
155    Derived d[3];
156
157    b1(n);
158    b1(cn);
159    b2(p);
160    b2(pm);
161    b2(a);
162    b2(am);
163    b2a(am); // expected-error {{no matching function}}
164    b3(d);
165    b3(cd);
166  }
167}
168
169namespace dr524 { // dr524: yes
170  template<typename T> void f(T a, T b) { operator+(a, b); } // expected-error {{call}}
171
172  struct S {};
173  void operator+(S, S);
174  template void f(S, S);
175
176  namespace N { struct S {}; }
177  void operator+(N::S, N::S); // expected-note {{should be declared}}
178  template void f(N::S, N::S); // expected-note {{instantiation}}
179}
180
181namespace dr525 { // dr525: yes
182  namespace before {
183    // Note, the example was correct prior to the change; instantiation is
184    // required for cases like this:
185    template <class T> struct D { operator T*(); };
186    void g(D<double> ppp) {
187      delete ppp;
188    }
189  }
190  namespace after {
191    template <class T> struct D { typename T::error e; }; // expected-error {{prior to '::'}}
192    void g(D<double> *ppp) {
193      delete ppp; // expected-note {{instantiation of}}
194    }
195  }
196}
197