1 // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1
2 // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
3 // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
4 // RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
5 // RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
6 
7 namespace dr2352 { // dr2352: 10
8   int **p;
f1()9   const int *const *const &f1() { return p; }
f2()10   int *const *const &f2() { return p; }
f3()11   int **const &f3() { return p; }
12 
f4()13   const int **const &f4() { return p; } // expected-error {{reference to type 'const int **const' could not bind to an lvalue of type 'int **'}}
f5()14   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}}
15 
16   // FIXME: We permit this as a speculative defect resolution, allowing
17   // qualification conversions when forming a glvalue conditional expression.
18   const int * const * const q = 0;
19   __typeof(&(true ? p : q)) x = &(true ? p : q);
20 
21   // FIXME: Should we compute the composite pointer type here and produce an
22   // lvalue of type 'const int *const * const'?
23   const int * const * r;
24   void *y = &(true ? p : r); // expected-error {{rvalue of type 'const int *const *'}}
25 
26   // FIXME: We order these as a speculative defect resolution.
27   void f(const int * const * const &r);
28 #if __cplusplus >= 201103L
29   constexpr
30 #endif
f(int * const * const & r)31   int *const *const &f(int * const * const &r) { return r; }
32 
33   // No temporary is created here.
34   int *const *const &check_f = f(p);
35 #if __cplusplus >= 201103L
36   static_assert(&p == &check_f, "");
37 #endif
38 }
39 
40 namespace dr2353 { // dr2353: 9
41   struct X {
42     static const int n = 0;
43   };
44 
45   // CHECK: FunctionDecl {{.*}} use
use(X x)46   int use(X x) {
47     // CHECK: MemberExpr {{.*}} .n
48     // CHECK-NOT: non_odr_use
49     // CHECK: DeclRefExpr {{.*}} 'x'
50     // CHECK-NOT: non_odr_use
51     return *&x.n;
52   }
53 #pragma clang __debug dump use
54 
55   // CHECK: FunctionDecl {{.*}} not_use
not_use(X x)56   int not_use(X x) {
57     // CHECK: MemberExpr {{.*}} .n {{.*}} non_odr_use_constant
58     // CHECK: DeclRefExpr {{.*}} 'x'
59     return x.n;
60   }
61 #pragma clang __debug dump not_use
62 
63   // CHECK: FunctionDecl {{.*}} not_use_2
not_use_2(X * x)64   int not_use_2(X *x) {
65     // CHECK: MemberExpr {{.*}} ->n {{.*}} non_odr_use_constant
66     // CHECK: DeclRefExpr {{.*}} 'x'
67     return x->n;
68   }
69 #pragma clang __debug dump not_use_2
70 }
71 
72 #if __cplusplus >= 201707L
73 // Otherwise, if the qualified-id std::tuple_size<E> names a complete class
74 // type **with a member value**, the expression std::tuple_size<E>::value shall
75 // be a well-formed integral constant expression
76 namespace dr2386 { // dr2386: 9
77 struct Bad1 { int a, b; };
78 struct Bad2 { int a, b; };
79 } // namespace dr2386
80 namespace std {
81 template <typename T> struct tuple_size;
82 template <> struct std::tuple_size<dr2386::Bad1> {};
83 template <> struct std::tuple_size<dr2386::Bad2> {
84   static const int value = 42;
85 };
86 } // namespace std
87 namespace dr2386 {
no_value()88 void no_value() { auto [x, y] = Bad1(); }
wrong_value()89 void wrong_value() { auto [x, y] = Bad2(); } // expected-error {{decomposes into 42 elements}}
90 } // namespace dr2386
91 #endif
92 
93 namespace dr2387 { // dr2387: 9
94 #if __cplusplus >= 201402L
95   template<int> int a = 0;
96   extern template int a<0>; // ok
97 
98   template<int> static int b = 0;
99   extern template int b<0>; // expected-error {{internal linkage}}
100 
101   template<int> const int c = 0;
102   extern template const int c<0>; // ok, has external linkage despite 'const'
103 
104   template<typename T> T d = 0;
105   extern template int d<int>;
106   extern template const int d<const int>;
107 #endif
108 }
109