File: ast-dump-recovery.c

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (150 lines) | stat: -rw-r--r-- 5,539 bytes parent folder | download | duplicates (9)
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
// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s

int some_func(int);

// CHECK:     VarDecl {{.*}} unmatch_arg_call 'int' cinit
// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
int unmatch_arg_call = some_func();

const int a = 1;

// CHECK:     VarDecl {{.*}} postfix_inc
// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'a'
int postfix_inc = a++;

// CHECK:     VarDecl {{.*}} unary_address
// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
// CHECK-NEXT:  `-ParenExpr {{.*}}
// CHECK-NEXT:    `-BinaryOperator {{.*}} '+'
// CHECK-NEXT:      |-ImplicitCastExpr
// CHECK-NEXT:      | `-DeclRefExpr {{.*}} 'a'
// CHECK-NEXT:      `-IntegerLiteral {{.*}} 'int'
int unary_address = &(a + 1);

// CHECK:       VarDecl {{.*}} ternary 'int' cinit
// CHECK-NEXT:  `-ConditionalOperator {{.*}}
// CHECK-NEXT:    |-DeclRefExpr {{.*}} 'a'
// CHECK-NEXT:    |-RecoveryExpr {{.*}}
// CHECK-NEXT:    `-DeclRefExpr {{.*}} 'a'
int ternary = a ? undef : a;

void test1() {
  // CHECK:     `-RecoveryExpr {{.*}} contains-errors
  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a' 'const int'
  static int foo = a++; // verify no crash on local static var decl.
}

void test2() {
  int* ptr;
  // CHECK:     BinaryOperator {{.*}} 'int *' contains-errors '='
  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'ptr' 'int *'
  // CHECK-NEXT: `-RecoveryExpr {{.*}}
  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
  ptr = some_func(); // should not crash

  int compoundOp;
  // CHECK:     CompoundAssignOperator {{.*}} 'int' contains-errors '+='
  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'compoundOp'
  // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
  compoundOp += some_func();

  // CHECK:     BinaryOperator {{.*}} 'int' contains-errors '||'
  // CHECK-NEXT: |-RecoveryExpr {{.*}}
  // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'some_func'
  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
  some_func() || 1;

  // CHECK:     BinaryOperator {{.*}} '<dependent type>' contains-errors ','
  // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1
  // CHECK-NEXT: `-RecoveryExpr {{.*}}
  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
  1, some_func();
  // CHECK:     BinaryOperator {{.*}} 'int' contains-errors ','
  // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>'
  // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'some_func'
  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
  some_func(), 1;

  // conditional operator (comparison is invalid)
  float f;
  // CHECK:     ConditionalOperator {{.*}} '<dependent type>' contains-errors
  // CHECK-NEXT: |-RecoveryExpr {{.*}} '<dependent type>'
  // CHECK-NEXT: | |-DeclRefExpr {{.*}} 'int *' lvalue
  // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'float' lvalue
  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'int *' lvalue
  // CHECK-NEXT: `-DeclRefExpr {{.*}} 'float' lvalue
  (ptr > f ? ptr : f);

  // CHECK:     CStyleCastExpr {{.*}} 'float' contains-errors <Dependent>
  // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
  // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
  (float)some_func();
}

void test3() {
  // CHECK:     CallExpr {{.*}} '<dependent type>' contains-errors
  // CHECK-NEXT: |-ParenExpr {{.*}} contains-errors lvalue
  // CHECK-NEXT: | `-RecoveryExpr {{.*}} contains-errors
  // CHECK-NEXT: |   `-DeclRefExpr {{.*}} '__builtin_classify_type'
  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
  (*__builtin_classify_type)(1);

  extern void ext();
  // CHECK:     CallExpr {{.*}} '<dependent type>' contains-errors
  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'ext'
  // CHECK-NEXT: `-RecoveryExpr {{.*}} '<dependent type>'
  ext(undef_var);
}

// Verify no crash.
void test4() {
  enum GH62446 {
    // CHECK:      RecoveryExpr {{.*}} '<dependent type>' contains-errors lvalue
    // CHECK-NEXT: |-StringLiteral {{.*}} "a"
    // CHECK-NEXT: `-IntegerLiteral {{.*}} 2
    invalid_enum_value = "a" * 2,
    b,
  };
}

// Verify no crash
void test5_GH62711() {
  // CHECK:      VAArgExpr {{.*}} 'int' contains-errors
  // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '<dependent type>' contains-errors
  // CHECK-NEXT: |   `-RecoveryExpr {{.*}} '<dependent type>' contains-errors
  if (__builtin_va_arg(undef, int) << 1);
}

void test6_GH50244() {
  double array[16];
  // CHECK:      UnaryExprOrTypeTraitExpr {{.*}} 'unsigned long' contains-errors sizeof
  // CHECK-NEXT: `-CallExpr {{.*}} '<dependent type>' contains-errors
  // CHECK-NEXT:   |-DeclRefExpr {{.*}} 'int ()'
  // CHECK-NEXT:   `-RecoveryExpr {{.*}} '<dependent type>'
  sizeof array / sizeof foo(undef);
}

// No crash on DeclRefExpr that refers to ValueDecl with invalid initializers.
void test7() {
  int b[] = {""()};

  // CHECK:      CStyleCastExpr {{.*}} 'unsigned int' contains-errors
  // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[]' contains-errors
  (unsigned) b; // GH50236

  // CHECK:      BinaryOperator {{.*}} '<dependent type>' contains-errors '+'
  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'int[]' contains-errors
  // CHECK-NEXT: `-IntegerLiteral {{.*}}
  b + 1; // GH50243

  // CHECK:      CallExpr {{.*}} '<dependent type>' contains-errors
  // CHECK-NEXT: |-DeclRefExpr {{.*}} 'int ()' Function
  // CHECK-NEXT: `-DeclRefExpr {{.*}} 'int[]' contains-errors
  return c(b); // GH48636
}
int test8_GH50320_b[] = {""()};
// CHECK: ArraySubscriptExpr {{.*}} 'int' contains-errors lvalue
int test8 = test_8GH50320_b[0];