xref: /llvm-project/clang/test/AST/ast-dump-recovery.cpp (revision 740861d69c2d2988ed69bc264df73bc5ae9d9e49)
1 // RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -std=gnu++17 -frecovery-ast -frecovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
2 // RUN: not %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -fcxx-exceptions -std=gnu++17 -fno-recovery-ast -ast-dump %s | FileCheck --check-prefix=DISABLED -strict-whitespace %s
3 
4 int some_func(int *);
5 
6 // CHECK:     VarDecl {{.*}} invalid_call
7 // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'int' contains-errors
8 // CHECK-NEXT:    |-UnresolvedLookupExpr {{.*}} 'some_func'
9 // CHECK-NEXT:    `-IntegerLiteral {{.*}} 123
10 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
11 int invalid_call = some_func(123);
12 void test_invalid_call_1(int s) {
13   // CHECK:      CallExpr {{.*}} '<dependent type>' contains-errors
14   // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} 'some_func'
15   // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:13>
16   // CHECK-NEXT: `-BinaryOperator {{.*}}
17   // CHECK-NEXT:   |-RecoveryExpr {{.*}}
18   // CHECK-NEXT:   `-IntegerLiteral {{.*}} <col:28> 'int' 1
19   some_func(undef1, undef2+1);
20 
21   // CHECK:      BinaryOperator {{.*}} '<dependent type>' contains-errors '='
22   // CHECK-NEXT: |-DeclRefExpr {{.*}} 's'
23   // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
24   // CHECK-NEXT:   |-UnresolvedLookupExpr {{.*}} 'some_func'
25   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
26   s = some_func(undef1);
27 
28   // CHECK:     VarDecl {{.*}} var 'int'
29   // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
30   // CHECK-NEXT:   |-UnresolvedLookupExpr {{.*}} 'some_func'
31   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
32   int var = some_func(undef1);
33 }
34 
35 int some_func2(int a, int b);
36 void test_invalid_call_2() {
37   // CHECK:   -RecoveryExpr {{.*}} 'int' contains-errors
38   // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} '<overloaded function type>' lvalue (ADL) = 'some_func2'
39   some_func2(,);
40 
41   // CHECK:   -RecoveryExpr {{.*}} 'int' contains-errors
42   // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} '<overloaded function type>' lvalue (ADL) = 'some_func2'
43   some_func2(,,);
44 
45   // CHECK:   `-RecoveryExpr {{.*}} 'int' contains-errors
46   // CHECK-NEXT: |-UnresolvedLookupExpr {{.*}} '<overloaded function type>' lvalue (ADL) = 'some_func2'
47   // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
48   some_func2(1,);
49 
50   // FIXME: Handle invalid argument with recovery
51   // CHECK-NOT: `-RecoveryExpr
52   some_func2(,1);
53 }
54 
55 int ambig_func(double);
56 int ambig_func(float);
57 
58 // CHECK:     VarDecl {{.*}} ambig_call
59 // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'int' contains-errors
60 // CHECK-NEXT:    |-UnresolvedLookupExpr {{.*}} 'ambig_func'
61 // CHECK-NEXT:    `-IntegerLiteral {{.*}} 123
62 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
63 int ambig_call = ambig_func(123);
64 
65 // CHECK:     VarDecl {{.*}} unresolved_call1
66 // CHECK-NEXT:`-RecoveryExpr {{.*}} '<dependent type>' contains-errors
67 // CHECK-NEXT:  `-UnresolvedLookupExpr {{.*}} 'bar'
68 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
69 int unresolved_call1 = bar();
70 
71 // CHECK:     VarDecl {{.*}} unresolved_call2
72 // CHECK-NEXT:`-CallExpr {{.*}} contains-errors
73 // CHECK-NEXT:  |-UnresolvedLookupExpr {{.*}} 'bar'
74 // CHECK-NEXT:  |-RecoveryExpr {{.*}} contains-errors
75 // CHECK-NEXT:  | `-UnresolvedLookupExpr {{.*}} 'baz'
76 // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
77 // CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'qux'
78 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
79 int unresolved_call2 = bar(baz(), qux());
80 
81 constexpr int a = 10;
82 
83 // CHECK:     VarDecl {{.*}} postfix_inc
84 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
85 // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a'
86 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
87 int postfix_inc = a++;
88 
89 // CHECK:     VarDecl {{.*}} prefix_inc
90 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
91 // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a'
92 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
93 int prefix_inc = ++a;
94 
95 // CHECK:     VarDecl {{.*}} unary_address
96 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
97 // CHECK-NEXT:  `-ParenExpr {{.*}}
98 // CHECK-NEXT:    `-BinaryOperator {{.*}} '+'
99 // CHECK-NEXT:      |-ImplicitCastExpr
100 // CHECK-NEXT:      | `-DeclRefExpr {{.*}} 'a'
101 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
102 int unary_address = &(a + 1);
103 
104 // CHECK:     VarDecl {{.*}} unary_bitinverse
105 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
106 // CHECK-NEXT:  `-ParenExpr {{.*}}
107 // CHECK-NEXT:    `-BinaryOperator {{.*}} '+'
108 // CHECK-NEXT:      |-ImplicitCastExpr
109 // CHECK-NEXT:      | `-ImplicitCastExpr
110 // CHECK-NEXT:      |   `-DeclRefExpr {{.*}} 'a'
111 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
112 int unary_bitinverse = ~(a + 0.0);
113 
114 // CHECK:     VarDecl {{.*}} binary
115 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
116 // CHECK-NEXT:  |-DeclRefExpr {{.*}} 'a'
117 // CHECK-NEXT:  `-CXXNullPtrLiteralExpr
118 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
119 int binary = a + nullptr;
120 
121 // CHECK:     VarDecl {{.*}} ternary
122 // CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
123 // CHECK-NEXT:  |-DeclRefExpr {{.*}} 'a'
124 // CHECK-NEXT:  |-CXXNullPtrLiteralExpr
125 // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a'
126 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
127 int ternary = a ? nullptr : a;
128 
129 // CHECK:     FunctionDecl
130 // CHECK-NEXT:|-ParmVarDecl {{.*}} x
131 // CHECK-NEXT:`-CompoundStmt
132 // CHECK-NEXT: |-RecoveryExpr {{.*}} contains-errors
133 // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'foo'
134 // CHECK-NEXT: `-CallExpr {{.*}} contains-errors
135 // CHECK-NEXT:  |-RecoveryExpr {{.*}} contains-errors
136 // CHECK-NEXT:  | `-DeclRefExpr {{.*}} 'foo'
137 // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'x'
138 struct Foo {} foo;
139 void test(int x) {
140   foo.abc;
141   foo->func(x);
142 }
143 
144 void AccessIncompleteClass() {
145   struct Forward;
146   Forward* ptr;
147   // CHECK:      CallExpr {{.*}} '<dependent type>'
148   // CHECK-NEXT: `-CXXDependentScopeMemberExpr {{.*}} '<dependent type>'
149   // CHECK-NEXT:   `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
150   // CHECK-NEXT:     `-DeclRefExpr {{.*}} 'Forward *'
151   ptr->method();
152 }
153 
154 struct Foo2 {
155   double func();
156   class ForwardClass;
157   ForwardClass createFwd();
158 
159   int overload();
160   int overload(int, int);
161 };
162 void test2(Foo2 f) {
163   // CHECK:      RecoveryExpr {{.*}} 'double'
164   // CHECK-NEXT:   |-MemberExpr {{.*}} '<bound member function type>'
165   // CHECK-NEXT:   | `-DeclRefExpr {{.*}} 'f'
166   // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
167   f.func(1);
168   // CHECK:      RecoveryExpr {{.*}} 'ForwardClass':'Foo2::ForwardClass'
169   // CHECK-NEXT: `-MemberExpr {{.*}} '<bound member function type>' .createFwd
170   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'f'
171   f.createFwd();
172   // CHECK:      RecoveryExpr {{.*}} 'int' contains-errors
173   // CHECK-NEXT: |-UnresolvedMemberExpr
174   // CHECK-NEXT:    `-DeclRefExpr {{.*}} 'Foo2'
175   // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
176   f.overload(1);
177 }
178 
179 // CHECK:     |-AlignedAttr {{.*}} alignas
180 // CHECK-NEXT:| `-RecoveryExpr {{.*}} contains-errors
181 // CHECK-NEXT:|   `-UnresolvedLookupExpr {{.*}} 'invalid'
182 struct alignas(invalid()) Aligned {};
183 
184 auto f();
185 int f(double);
186 // CHECK:      VarDecl {{.*}} unknown_type_call 'int'
187 // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
188 int unknown_type_call = f(0, 0);
189 
190 void InvalidInitalizer(int x) {
191   struct Bar { Bar(); };
192   // CHECK:     `-VarDecl {{.*}} a1 'Bar'
193   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
194   // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
195   Bar a1(1);
196   // CHECK:     `-VarDecl {{.*}} a2 'Bar'
197   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
198   // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'x'
199   Bar a2(x);
200   // CHECK:     `-VarDecl {{.*}} a3 'Bar'
201   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
202   // CHECK-NEXT:  `-InitListExpr
203   // CHECK-NEDT:   `-DeclRefExpr {{.*}} 'x'
204   Bar a3{x};
205   // CHECK:     `-VarDecl {{.*}} a4 'Bar'
206   // CHECK-NEXT: `-ParenListExpr {{.*}} 'NULL TYPE' contains-errors
207   // CHECK-NEXT:  `-RecoveryExpr {{.*}} contains-errors
208   // CHECK-NEXT:   `-UnresolvedLookupExpr {{.*}} 'invalid'
209   Bar a4(invalid());
210   // CHECK:     `-VarDecl {{.*}} a5 'Bar'
211   // CHECK-NEXT: `-InitListExpr {{.*}} contains-errors
212   // CHECK-NEXT:  `-RecoveryExpr {{.*}} contains-errors
213   // CHECK-NEXT:   `-UnresolvedLookupExpr {{.*}} 'invalid'
214   Bar a5{invalid()};
215 
216   // CHECK:     `-VarDecl {{.*}} b1 'Bar'
217   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
218   // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
219   Bar b1 = 1;
220   // CHECK:     `-VarDecl {{.*}} b2 'Bar'
221   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
222   // CHECK-NEXT:  `-InitListExpr
223   Bar b2 = {1};
224   // CHECK:     `-VarDecl {{.*}} b3 'Bar'
225   // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
226   // CHECK-NEXT:    `-DeclRefExpr {{.*}} 'x' 'int'
227   Bar b3 = Bar(x);
228   // CHECK:     `-VarDecl {{.*}} b4 'Bar'
229   // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
230   // CHECK-NEXT:    `-InitListExpr {{.*}} 'void'
231   // CHECK-NEXT:      `-DeclRefExpr {{.*}} 'x' 'int'
232   Bar b4 = Bar{x};
233   // CHECK:     `-VarDecl {{.*}} b5 'Bar'
234   // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 'Bar'
235   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
236   // CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'invalid'
237   Bar b5 = Bar(invalid());
238   // CHECK:     `-VarDecl {{.*}} b6 'Bar'
239   // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 'Bar'
240   // CHECK-NEXT:  `-InitListExpr {{.*}} contains-errors
241   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
242   // CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'invalid'
243   Bar b6 = Bar{invalid()};
244 
245   // CHECK:     RecoveryExpr {{.*}} 'Bar' contains-errors
246   // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
247   Bar(1);
248 
249   // CHECK:     `-VarDecl {{.*}} var1
250   // CHECK-NEXT: `-BinaryOperator {{.*}} '<dependent type>' contains-errors
251   // CHECK-NEXT:   |-RecoveryExpr {{.*}} '<dependent type>' contains-errors
252   // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 1
253   int var1 = undef + 1;
254 }
255 void InitializerForAuto() {
256   // CHECK:     `-VarDecl {{.*}} invalid a 'auto'
257   // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
258   // CHECK-NEXT:   `-UnresolvedLookupExpr {{.*}} 'invalid'
259   auto a = invalid();
260 
261   // CHECK:     `-VarDecl {{.*}} invalid b 'auto'
262   // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
263   // CHECK-NEXT:   |-UnresolvedLookupExpr {{.*}} 'some_func'
264   // CHECK-NEXT:   `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
265   // CHECK-NEXT:     `-UnresolvedLookupExpr {{.*}} 'invalid'
266   auto b = some_func(invalid());
267 
268   decltype(ned);
269   // very bad initailizer: there is an unresolved typo expr internally, we just
270   // drop it.
271   // CHECK: `-VarDecl {{.*}} invalid unresolved_typo 'auto'
272   auto unresolved_typo = gned.*[] {};
273 }
274 
275 // Verified that the generated call operator is invalid.
276 // CHECK: |-CXXMethodDecl {{.*}} invalid operator() 'auto () const -> auto'
277 using Escape = decltype([] { return undef(); }());
278 
279 // CHECK:      VarDecl {{.*}} NoCrashOnInvalidInitList
280 // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors lvalue
281 // CHECK-NEXT:   `-InitListExpr
282 // CHECK-NEXT:     `-DesignatedInitExpr {{.*}} 'void'
283 // CHECK-NEXT:       `-CXXNullPtrLiteralExpr {{.*}} 'std::nullptr_t'
284 struct {
285   int& abc;
286 } NoCrashOnInvalidInitList = {
287   .abc = nullptr,
288 };
289 
290 // Verify the value category of recovery expression.
291 int prvalue(int);
292 int &lvalue(int);
293 int &&xvalue(int);
294 void ValueCategory() {
295   // CHECK:  RecoveryExpr {{.*}} 'int' contains-errors
296   prvalue(); // call to a function (nonreference return type) yields a prvalue (not print by default)
297   // CHECK:  RecoveryExpr {{.*}} 'int' contains-errors lvalue
298   lvalue(); // call to a function (lvalue reference return type) yields an lvalue.
299   // CHECK:  RecoveryExpr {{.*}} 'int' contains-errors xvalue
300   xvalue(); // call to a function (rvalue reference return type) yields an xvalue.
301 }
302 
303 void InvalidCondition() {
304   // CHECK:      IfStmt {{.*}}
305   // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:7, col:15> '<dependent type>' contains-errors
306   // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:7>
307   if (invalid()) {}
308 
309   // CHECK:      WhileStmt {{.*}}
310   // CHECK-NEXT: |-RecoveryExpr {{.*}} <col:10, col:18> '<dependent type>' contains-errors
311   // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10>
312   while (invalid()) {}
313 
314   // CHECK:      SwitchStmt {{.*}}
315   // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors
316   // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} <col:10>
317   switch(invalid()) {
318     case 1:
319       break;
320   }
321   // FIXME: figure out why the type of ConditionalOperator is not int.
322   // CHECK:      ConditionalOperator {{.*}} '<dependent type>' contains-errors
323   // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>' contains-errors
324   // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}}
325   // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1
326   // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2
327   invalid() ? 1 : 2;
328 }
329 
330 void CtorInitializer() {
331   struct S{int m};
332   class MemberInit {
333     int x, y, z;
334     S s;
335     MemberInit() : x(invalid), y(invalid, invalid), z(invalid()), s(1,2) {}
336     // CHECK:      CXXConstructorDecl {{.*}} MemberInit 'void ()'
337     // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'x' 'int'
338     // CHECK-NEXT: | `-ParenListExpr
339     // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
340     // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'y' 'int'
341     // CHECK-NEXT: | `-ParenListExpr
342     // CHECK-NEXT: |   |-RecoveryExpr {{.*}} '<dependent type>'
343     // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
344     // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 'z' 'int'
345     // CHECK-NEXT: | `-ParenListExpr
346     // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
347     // CHECK-NEXT: |     `-UnresolvedLookupExpr {{.*}} '<overloaded function type>'
348     // CHECK-NEXT: |-CXXCtorInitializer Field {{.*}} 's' 'S'
349     // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'S' contains-errors
350     // CHECK-NEXT: |   |-IntegerLiteral {{.*}} 1
351     // CHECK-NEXT: |   `-IntegerLiteral {{.*}} 2
352   };
353   class BaseInit : S {
354     BaseInit(float) : S("no match") {}
355     // CHECK:      CXXConstructorDecl {{.*}} BaseInit 'void (float)'
356     // CHECK-NEXT: |-ParmVarDecl
357     // CHECK-NEXT: |-CXXCtorInitializer 'S'
358     // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'S'
359     // CHECK-NEXT: |   `-StringLiteral
360 
361     BaseInit(double) : S(invalid) {}
362     // CHECK:      CXXConstructorDecl {{.*}} BaseInit 'void (double)'
363     // CHECK-NEXT: |-ParmVarDecl
364     // CHECK-NEXT: |-CXXCtorInitializer 'S'
365     // CHECK-NEXT: | `-ParenListExpr
366     // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
367   };
368   class DelegatingInit {
369     DelegatingInit(float) : DelegatingInit("no match") {}
370     // CHECK:      CXXConstructorDecl {{.*}} DelegatingInit 'void (float)'
371     // CHECK-NEXT: |-ParmVarDecl
372     // CHECK-NEXT: |-CXXCtorInitializer 'DelegatingInit'
373     // CHECK-NEXT: | `-RecoveryExpr {{.*}} 'DelegatingInit'
374     // CHECK-NEXT: |   `-StringLiteral
375 
376     DelegatingInit(double) : DelegatingInit(invalid) {}
377     // CHECK:      CXXConstructorDecl {{.*}} DelegatingInit 'void (double)'
378     // CHECK-NEXT: |-ParmVarDecl
379     // CHECK-NEXT: |-CXXCtorInitializer 'DelegatingInit'
380     // CHECK-NEXT: | `-ParenListExpr
381     // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>'
382   };
383 }
384 
385 float *brokenReturn() {
386   // CHECK:      FunctionDecl {{.*}} brokenReturn
387   return 42;
388   // CHECK:      ReturnStmt
389   // CHECK-NEXT: `-RecoveryExpr {{.*}} 'float *'
390   // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 42
391 }
392 
393 // Return deduction treats the first, second *and* third differently!
394 auto *brokenDeducedReturn(int *x, float *y, double *z) {
395   // CHECK:      FunctionDecl {{.*}} invalid brokenDeducedReturn
396   if (x) return x;
397   // CHECK:      ReturnStmt
398   // CHECK-NEXT: `-ImplicitCastExpr {{.*}} <LValueToRValue>
399   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'x' 'int *'
400   if (y) return y;
401   // CHECK:      ReturnStmt
402   // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int *'
403   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'y' 'float *'
404   if (z) return z;
405   // CHECK:      ReturnStmt
406   // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int *'
407   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'z' 'double *'
408   return x;
409   // Unfortunate: we wrap a valid return in RecoveryExpr.
410   // This is to avoid running deduction again after it failed once.
411   // CHECK:      ReturnStmt
412   // CHECK-NEXT: `-RecoveryExpr {{.*}} 'int *'
413   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'x' 'int *'
414 }
415 
416 void returnInitListFromVoid() {
417   // CHECK:      FunctionDecl {{.*}} returnInitListFromVoid
418   return {7,8};
419   // CHECK:      ReturnStmt
420   // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
421   // CHECK-NEXT:   |-IntegerLiteral {{.*}} 'int' 7
422   // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 8
423 }
424 
425 void RecoveryExprForInvalidDecls(Unknown InvalidDecl) {
426   InvalidDecl + 1;
427   // CHECK:      BinaryOperator {{.*}}
428   // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>'
429   // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'InvalidDecl' 'int'
430   // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
431   InvalidDecl();
432   // CHECK:      CallExpr {{.*}}
433   // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
434 }
435 
436 void InitializerOfInvalidDecl() {
437   int ValidDecl;
438   Unkown InvalidDecl = ValidDecl;
439   // CHECK:      VarDecl {{.*}} invalid InvalidDecl
440   // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
441   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'ValidDecl'
442 
443   Unknown InvalidDeclWithInvalidInit = Invalid;
444   // CHECK:      VarDecl {{.*}} invalid InvalidDeclWithInvalidInit
445   // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
446   // CHECK-NOT:    `-TypoExpr
447 }
448 
449 void RecoverToAnInvalidDecl() {
450   Unknown* foo; // invalid decl
451   goo; // the typo was correct to the invalid foo.
452   // Verify that RecoveryExpr has an inner DeclRefExpr.
453   // CHECK:      RecoveryExpr {{.*}} '<dependent type>' contains-errors lvalue
454   // CHECK-NEXT: `-DeclRefExpr {{.*}} 'foo' 'int *'
455 }
456 
457 void RecoveryToDoWhileStmtCond() {
458   // CHECK:       FunctionDecl {{.*}} RecoveryToDoWhileStmtCond
459   // CHECK:       `-DoStmt {{.*}}
460   // CHECK-NEXT:    |-CompoundStmt {{.*}}
461   // CHECK-NEXT:    `-BinaryOperator {{.*}} '<dependent type>' contains-errors '<'
462   // CHECK-NEXT:      |-BinaryOperator {{.*}} '<dependent type>' contains-errors '+'
463   // CHECK-NEXT:      | |-RecoveryExpr {{.*}} '<dependent type>' contains-errors lvalue
464   // CHECK-NEXT:      | `-IntegerLiteral {{.*}} 'int' 1
465   // CHECK-NEXT:      `-IntegerLiteral {{.*}} 'int' 10
466   do {} while (some_invalid_val + 1 < 10);
467 }
468 
469 void RecoveryForStmtCond() {
470   // CHECK:FunctionDecl {{.*}} RecoveryForStmtCond
471   // CHECK-NEXT:`-CompoundStmt {{.*}}
472   // CHECK-NEXT:  `-ForStmt {{.*}}
473   // CHECK-NEXT:    |-DeclStmt {{.*}}
474   // CHECK-NEXT:    | `-VarDecl {{.*}}
475   // CHECK-NEXT:    |   `-IntegerLiteral {{.*}} <col:16> 'int' 0
476   // CHECK-NEXT:    |-<<<NULL>>>
477   // CHECK-NEXT:    |-RecoveryExpr {{.*}} 'bool' contains-errors
478   // CHECK-NEXT:    |-UnaryOperator {{.*}} 'int' lvalue prefix '++'
479   // CHECK-NEXT:    | `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'i' 'int'
480   // CHECK-NEXT:    `-CompoundStmt {{.*}}
481   for (int i = 0; i < invalid; ++i) {}
482 }
483 
484 // Fix crash issue https://github.com/llvm/llvm-project/issues/112560.
485 // Make sure clang compiles the following code without crashing:
486 
487 // CHECK:NamespaceDecl {{.*}} GH112560
488 // CHECK-NEXT:  |-CXXRecordDecl {{.*}} referenced union U definition
489 // CHECK-NEXT:  | |-DefinitionData {{.*}}
490 // CHECK-NEXT:  | | |-DefaultConstructor {{.*}}
491 // CHECK-NEXT:  | | |-CopyConstructor {{.*}}
492 // CHECK-NEXT:  | | |-MoveConstructor {{.*}}
493 // CHECK-NEXT:  | | |-CopyAssignment {{.*}}
494 // CHECK-NEXT:  | | |-MoveAssignment {{.*}}
495 // CHECK-NEXT:  | | `-Destructor {{.*}}
496 // CHECK-NEXT:  | |-CXXRecordDecl {{.*}} implicit union U
497 // CHECK-NEXT:  | `-FieldDecl {{.*}} invalid f 'int'
498 // CHECK-NEXT:  |   `-RecoveryExpr {{.*}} 'int' contains-errors
499 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
500 namespace GH112560 {
501 union U {
502   int f = ;
503 };
504 
505 // CHECK: FunctionDecl {{.*}} foo 'void ()'
506 // CHECK-NEXT:    `-CompoundStmt {{.*}}
507 // CHECK-NEXT:      `-DeclStmt {{.*}}
508 // CHECK-NEXT:        `-VarDecl {{.*}} g 'U':'GH112560::U' listinit
509 // CHECK-NEXT:          `-InitListExpr {{.*}} 'U':'GH112560::U' contains-errors field Field {{.*}} 'f' 'int'
510 // CHECK-NEXT:            `-CXXDefaultInitExpr {{.*}} 'int' contains-errors has rewritten init
511 // CHECK-NEXT:              `-RecoveryExpr {{.*}} 'int' contains-errors
512 // DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
513 void foo() {
514   U g{};
515 }
516 } // namespace GH112560
517