aboutsummaryrefslogtreecommitdiff
path: root/clang/test/CXX/drs/dr23xx.cpp
blob: 9ced61d2aae30dc5e4ebf0239802f9d4dbf419ce (plain)
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
// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
// RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14,since-cxx17,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s

#if __cplusplus >= 201103L
namespace dr2303 { // dr2303: 12
template <typename... T>
struct A;
template <>
struct A<> {};
template <typename T, typename... Ts>
struct A<T, Ts...> : A<Ts...> {};
struct B : A<int, int> {};
struct C : A<int, int>, A<int> {};
/* since-cxx11-warning@-1 {{direct base 'A<int>' is inaccessible due to ambiguity:
    struct dr2303::C -> A<int, int> -> A<int>
    struct dr2303::C -> A<int>}} */
struct D : A<int>, A<int, int> {};
/* since-cxx11-warning@-1 {{direct base 'A<int>' is inaccessible due to ambiguity:
    struct dr2303::D -> A<int>
    struct dr2303::D -> A<int, int> -> A<int>}} */
struct E : A<int, int> {};
struct F : B, E {};

template <typename... T>
void f(const A<T...> &) {
  static_assert(sizeof...(T) == 2, "Should only match A<int,int>");
}
template <typename... T>
void f2(const A<T...> *);

void g() {
  f(B{}); // This is no longer ambiguous.
  B b;
  f2(&b);
  f(C{});
  f(D{});
  f(F{});
  /* since-cxx11-error@-1 {{ambiguous conversion from derived class 'const F' to base class 'const A<int, int>':
    struct dr2303::F -> B -> A<int, int>
    struct dr2303::F -> E -> A<int, int>}} */
}
} //namespace dr2303
#endif

// dr2331: na

#if __cplusplus >= 201103L
namespace dr2338 { // dr2338: 12
namespace B {
enum E : bool { Zero, One };
static_assert((int)(E)2 == 1, "");
} // namespace B
namespace D {
enum class E : bool { Zero, One };
static_assert((int)(E)2 == 1, "");
} // namespace D
} // namespace dr2338
#endif

namespace dr2346 { // dr2346: 11
  void test() {
    const int i2 = 0;
    extern void h2b(int x = i2 + 0); // ok, not odr-use
  }
}

namespace dr2352 { // dr2352: 10
  int **p;
  const int *const *const &f1() { return p; }
  int *const *const &f2() { return p; }
  int **const &f3() { return p; }

  const int **const &f4() { return p; }
  // expected-error@-1 {{reference to type 'const int **const' could not bind to an lvalue of type 'int **'}}
  const int *const *&f5() { return p; }
  // expected-error@-1 {{binding reference of type 'const int *const *' to value of type 'int **' not permitted due to incompatible qualifiers}}

  // FIXME: We permit this as a speculative defect resolution, allowing
  // qualification conversions when forming a glvalue conditional expression.
  const int * const * const q = 0;
  __typeof(&(true ? p : q)) x = &(true ? p : q);

  // FIXME: Should we compute the composite pointer type here and produce an
  // lvalue of type 'const int *const * const'?
  const int * const * r;
  void *y = &(true ? p : r);
  // expected-error@-1 {{rvalue of type 'const int *const *'}}

  // FIXME: We order these as a speculative defect resolution.
  void f(const int * const * const &r);
#if __cplusplus >= 201103L
  constexpr
#endif
  int *const *const &f(int * const * const &r) { return r; }

  // No temporary is created here.
  int *const *const &check_f = f(p);
#if __cplusplus >= 201103L
  static_assert(&p == &check_f, "");
#endif
}

namespace dr2353 { // dr2353: 9
  struct X {
    static const int n = 0;
  };

  // CHECK: FunctionDecl {{.*}} use
  int use(X x) {
    // CHECK: MemberExpr {{.*}} .n
    // CHECK-NOT: non_odr_use
    // CHECK: DeclRefExpr {{.*}} 'x'
    // CHECK-NOT: non_odr_use
    return *&x.n;
  }
#pragma clang __debug dump use

  // CHECK: FunctionDecl {{.*}} not_use
  int not_use(X x) {
    // CHECK: MemberExpr {{.*}} .n {{.*}} non_odr_use_constant
    // CHECK: DeclRefExpr {{.*}} 'x'
    return x.n;
  }
#pragma clang __debug dump not_use

  // CHECK: FunctionDecl {{.*}} not_use_2
  int not_use_2(X *x) {
    // CHECK: MemberExpr {{.*}} ->n {{.*}} non_odr_use_constant
    // CHECK: DeclRefExpr {{.*}} 'x'
    return x->n;
  }
#pragma clang __debug dump not_use_2
}

namespace dr2354 { // dr2354: 15
#if __cplusplus >= 201103L
enum alignas(64) A {};
// since-cxx11-error@-1 {{'alignas' attribute cannot be applied to an enumeration}}
enum struct alignas(64) B {};
// since-cxx11-error@-1 {{'alignas' attribute cannot be applied to an enumeration}}
#endif
} // namespace dr2354

#if __cplusplus >= 201402L
namespace dr2358 { // dr2358: 16
  void f2() {
    int i = 1;
    void g1(int = [xxx=1] { return xxx; }());  // OK
    void g2(int = [xxx=i] { return xxx; }());
    // since-cxx14-error@-1 {{default argument references local variable 'i' of enclosing function}}
  }
}
#endif

namespace dr2370 { // dr2370: no
namespace N {
typedef int type;
void g(type);
void h(type);
} // namespace N
class C {
  typedef N::type N_type;
  // FIXME: `type` should be searched for in N
  // friend void N::g(type);
  friend void N::h(N_type);
};
} // namespace dr2370

#if __cplusplus >= 201702L
// Otherwise, if the qualified-id std::tuple_size<E> names a complete class
// type **with a member value**, the expression std::tuple_size<E>::value shall
// be a well-formed integral constant expression
namespace dr2386 { // dr2386: 9
struct Bad1 { int a, b; };
struct Bad2 { int a, b; };
} // namespace dr2386
namespace std {
template <typename T> struct tuple_size;
template <> struct std::tuple_size<dr2386::Bad1> {};
template <> struct std::tuple_size<dr2386::Bad2> {
  static const int value = 42;
};
} // namespace std
namespace dr2386 {
void no_value() { auto [x, y] = Bad1(); }
void wrong_value() { auto [x, y] = Bad2(); }
// since-cxx17-error@-1 {{type 'Bad2' decomposes into 42 elements, but only 2 names were provided}}
} // namespace dr2386
#endif

// dr2385: na

namespace dr2387 { // dr2387: 9
#if __cplusplus >= 201402L
  template<int> int a = 0;
  extern template int a<0>; // ok

  template<int> static int b = 0;
  extern template int b<0>;
  // since-cxx14-error@-1 {{explicit instantiation declaration of 'b<0>' with internal linkage}}

  template<int> const int c = 0;
  extern template const int c<0>; // ok, has external linkage despite 'const'

  template<typename T> T d = 0;
  extern template int d<int>;
  extern template const int d<const int>;
#endif
}

namespace dr2394 { // dr2394: 15

struct A {};
const A a;

// Now allowed to default-init B.
struct B { const A a; };
B b;

}

namespace dr2396 { // dr2396: no
  struct A {
    struct B;
    operator B B::*();
  };
  struct B;

  // FIXME: per P1787 "Calling a conversion function" example, all of the
  // examples below are well-formed, with B resolving to A::B, but currently
  // it's been resolved to dr2396::B. 

  // void f(A a) { a.operator B B::*(); }            
  // void g(A a) { a.operator decltype(B()) B::*(); }
  // void g2(A a) { a.operator B decltype(B())::*(); }
}

#if __cplusplus >= 201103L
namespace dr2397 { // dr2397: 17
  void foo() {
    int a[5];

    auto (&b)[5] = a;
    auto (*c)[5] = &a;
  }
} // namespace dr2397
#endif