xref: /llvm-project/clang/test/SemaCXX/recovery-expr-type.cpp (revision 4447461bc4802d4ead02db61c5276c142df3fd0c)
1 // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++17 -fsyntax-only -verify -fexperimental-new-constant-interpreter
2 // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++20 -fsyntax-only -verify -fexperimental-new-constant-interpreter
3 // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++17 -fsyntax-only -verify
4 // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -o - %s -std=gnu++20 -fsyntax-only -verify
5 
6 
7 namespace test0 {
8 struct Indestructible {
9   // Indestructible();
10   ~Indestructible() = delete; // expected-note 2{{deleted}}
11 };
12 Indestructible make_indestructible();
13 
test()14 void test() {
15   // no crash.
16   int s = sizeof(make_indestructible()); // expected-error {{deleted}}
17   constexpr int ss = sizeof(make_indestructible()); // expected-error {{deleted}}
18   static_assert(ss, "");
19   int array[ss];
20 }
21 }
22 
23 namespace test1 {
foo()24 constexpr int foo() { return 1; } // expected-note {{candidate function not viable}}
25 // verify the "not an integral constant expression" diagnostic is suppressed.
26 static_assert(1 == foo(1), ""); // expected-error {{no matching function}}
27 }
28 
29 namespace test2 {
30 void foo(); // expected-note 3{{requires 0 arguments}}
func()31 void func() {
32   // verify that "field has incomplete type" diagnostic is suppressed.
33   typeof(foo(42)) var; // expected-error {{no matching function}} \
34 
35   // FIXME: suppress the "cannot initialize a variable" diagnostic.
36   int a = foo(1); // expected-error {{no matching function}} \
37                   // expected-error {{cannot initialize a variable of type}}
38 
39   // FIXME: suppress the "invalid application" diagnostic.
40   int s = sizeof(foo(42)); // expected-error {{no matching function}} \
41                            // expected-error {{invalid application of 'sizeof'}}
42 };
43 }
44 
45 namespace test3 {
46 template <int N>
templated()47 constexpr int templated() __attribute__((enable_if(N, ""))) { // expected-note {{candidate disabled}}
48   return 1;
49 }
50 // verify that "constexpr variable must be initialized" diagnostic is suppressed.
51 constexpr int A = templated<0>(); // expected-error{{no matching function}}
52 
53 template <typename T>
54 struct AA {
55   template <typename U>
getBtest3::AA56   static constexpr int getB() { // expected-note{{candidate template ignored}}
57     return 2;
58   }
foo2test3::AA59   static constexpr int foo2() {
60     return AA<T>::getB(); // expected-error{{no matching function for call to 'getB'}}
61   }
62 };
63 // FIXME: should we suppress the "be initialized by a constant expression" diagnostic?
64 constexpr auto x2 = AA<int>::foo2(); // expected-error {{be initialized by a constant expression}} \
65                                      // expected-note {{in instantiation of member function}}
66 }
67 
68 // verify no assertion failure on violating value category.
69 namespace test4 {
70 int &&f(int);  // expected-note {{candidate function not viable}}
71 int &&k = f(); // expected-error {{no matching function for call}}
72 }
73 
74 // verify that "type 'double' cannot bind to a value of unrelated type 'int'" diagnostic is suppressed.
75 namespace test5 {
76   template<typename T> using U = T; // expected-note {{template parameter is declared here}}
77   template<typename...Ts> U<Ts...>& f(); // expected-error {{pack expansion used as argument for non-pack parameter of alias template}}
78   double &s1 = f(); // expected-error {{no matching function}}
79 }
80 
81 namespace test6 {
82 struct T {
83   T() = delete; // expected-note {{has been explicitly marked deleted here}}
84 };
85 
func()86 void func() {
87   // verify that no -Wunused-value diagnostic.
88   (T(T())); // expected-error {{call to deleted constructor}}
89 }
90 }
91 
92 // verify the secondary diagnostic "no matching function" is emitted.
93 namespace test7 {
94 struct C {
95   C() = delete; // expected-note {{has been explicitly marked deleted}}
96 };
97 void f(C &); // expected-note {{candidate function not viable: expects an lvalue for 1st argument}}
test()98 void test() {
99   f(C()); // expected-error {{call to deleted constructor}} \
100              expected-error {{no matching function for call}}
101 }
102 }
103 
104 // verify the secondary diagnostic "cannot initialize" is emitted.
105 namespace test8 {
106 typedef int arr[];
107 int v = arr(); // expected-error {{array types cannot be value-initialized}} \
108                   expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'arr'}}
109 }
110 
111 namespace test9 {
112 auto f(); // expected-note {{candidate function not viable}}
113 // verify no crash on evaluating the size of undeduced auto type.
114 static_assert(sizeof(f(1)), ""); // expected-error {{no matching function for call to 'f'}}
115 }
116 
117 namespace test10 {
118 // Ensure we don't assert here.
119 int f(); // expected-note {{candidate}}
120 template<typename T> const int k = f(T()); // expected-error {{no matching function}}
121 static_assert(k<int> == 1, ""); // expected-note {{instantiation of}}
122 }
123 
124 namespace test11 {
125 // Verify we do not assert()-fail here.
126 template <class T> void foo(T &t);
127 template <typename T>
bar(T t)128 void bar(T t) {
129   foo(t);
130 }
131 
132 template <typename T = void *>
133 struct S { // expected-note {{candidate}}
134   S(T t);  // expected-note {{candidate}}
135   ~S();
136 };
137 template <typename T> S(T t) -> S<void *>;
138 
baz()139 void baz() {
140   bar(S(123)); // expected-error {{no matching conversion for functional-style cast from 'int' to 'S<void *>'}}
141 }
142 } // namespace test11
143 
144 namespace test12 {
145 // Verify we do not crash.
146 int fun(int *foo = no_such_function()); // expected-error {{undeclared identifier}}
crash1()147 void crash1() { fun(); }
crash2()148 void crash2() { constexpr int s = fun(); }
149 } // namespace test12
150 
151 namespace test13 {
152 enum Circular {             // expected-note {{not complete until the closing '}'}}
153   Circular_A = Circular(1), // expected-error {{'Circular' is an incomplete type}}
154 };
155 // Enumerators can be evaluated (they evaluate as zero, but we don't care).
156 static_assert(Circular_A == 0 && Circular_A != 0, ""); // expected-error {{static assertion failed}} \
157                                                        // expected-note {{evaluates to '0 != 0'}}
158 }
159 
160 namespace test14 {
memset(void *,int b,unsigned long)161 extern "C" void *memset(void *, int b, unsigned long) {
162   int * const c(undef()); // expected-error {{undeclared identifier}}
163   // Verify we do not crash on evaluating *c whose initializer is a NULL-type ParenListExpr!
164   memset(c, 0, *c); // crash1
165 
166   b = __builtin_object_size(c, 0); // crash2
167 }
168 }
169 
170 namespace test15 {
f()171 void f() {
172   struct {
173     void m(int (&)[undefined()]) {} // expected-error {{undeclared identifier}}
174   } S;
175   S.m(1); // no crash
176 }
177 }
178 
179 namespace test16 {
180 // verify we do not crash on incomplete class type.
181 template<typename T, typename U> struct A; // expected-note 5{{template is declared here}}
foo()182 A<int, int> foo() { // expected-error {{implicit instantiation of undefined template}}
183   if (1 == 1)
184     return A<int, int>{1}; // expected-error 2{{implicit instantiation of undefined template}}
185   return A<int, int>(1); // expected-error 2{{implicit instantiation of undefined template}}
186 }
187 }
188