dr23xx.cpp
4.93 KB
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
// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1
// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
#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 {{reference to type 'const int **const' could not bind to an lvalue of type 'int **'}}
const int *const *&f5() { return p; } // expected-error {{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 {{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
}
#if __cplusplus >= 201707L
// 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(); } // expected-error {{decomposes into 42 elements}}
} // namespace dr2386
#endif
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>; // expected-error {{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
}
#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> {}; // expected-warning {{direct base 'A<int>' is inaccessible}}
struct D : A<int>, A<int, int> {}; // expected-warning {{direct base 'A<int>' is inaccessible}}
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{}); // expected-error {{ambiguous conversion from derived class}}
}
} //namespace dr2303
#endif