1 // RUN: %clang_analyze_cc1 -w -analyzer-checker=debug.DumpLiveExprs %s 2>&1\ 2 // RUN: | FileCheck %s 3 4 int coin(); 5 6 7 int testThatDumperWorks(int x, int y, int z) { 8 return x ? y : z; 9 } 10 11 // [B5 (ENTRY)] 12 // | 13 // V 14 // [B4 (x)] ? [B2 (y)] : [B3 (z)] 15 // \ / 16 // ---|---- 17 // V 18 // [B1] --> [B0 (EXIT)] 19 // return 20 21 // CHECK: [ B0 (live expressions at block exit) ] 22 // CHECK-EMPTY: 23 // CHECK-EMPTY: 24 // CHECK: [ B1 (live expressions at block exit) ] 25 // CHECK-EMPTY: 26 // CHECK-EMPTY: 27 // CHECK: [ B2 (live expressions at block exit) ] 28 // CHECK-EMPTY: 29 // CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int' 30 // CHECK-EMPTY: 31 // CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int' 32 // CHECK-EMPTY: 33 // CHECK-NEXT: ImplicitCastExpr {{.*}} <IntegralToBoolean> 34 // CHECK-NEXT: `-ImplicitCastExpr {{.*}} <LValueToRValue> 35 // CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' 'int' 36 // CHECK-EMPTY: 37 // CHECK-EMPTY: 38 // CHECK: [ B3 (live expressions at block exit) ] 39 // CHECK-EMPTY: 40 // CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int' 41 // CHECK-EMPTY: 42 // CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int' 43 // CHECK-EMPTY: 44 // CHECK-NEXT: ImplicitCastExpr {{.*}} <IntegralToBoolean> 45 // CHECK-NEXT: `-ImplicitCastExpr {{.*}} <LValueToRValue> 46 // CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' 'int' 47 // CHECK: [ B4 (live expressions at block exit) ] 48 // CHECK-EMPTY: 49 // CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int' 50 // CHECK-EMPTY: 51 // CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int' 52 // CHECK-EMPTY: 53 // CHECK-NEXT: ImplicitCastExpr {{.*}} <IntegralToBoolean> 54 // CHECK-NEXT: `-ImplicitCastExpr {{.*}} <LValueToRValue> 55 // CHECK-NEXT: `-DeclRefExpr {{.*}} 'x' 'int' 56 // CHECK-EMPTY: 57 // CHECK-EMPTY: 58 // CHECK: [ B5 (live expressions at block exit) ] 59 // CHECK-EMPTY: 60 // CHECK-NEXT: DeclRefExpr {{.*}} 'y' 'int' 61 // CHECK-EMPTY: 62 // CHECK-NEXT: DeclRefExpr {{.*}} 'z' 'int' 63 // CHECK-EMPTY: 64 // CHECK-EMPTY: 65 66 67 void testIfBranchExpression(bool flag) { 68 // No expressions should be carried over from one block to another here. 69 while (flag) { 70 int e = 1; 71 if (true) 72 e; 73 } 74 } 75 // CHECK: [ B0 (live expressions at block exit) ] 76 // CHECK-EMPTY: 77 // CHECK-EMPTY: 78 // CHECK: [ B1 (live expressions at block exit) ] 79 // CHECK-EMPTY: 80 // CHECK-EMPTY: 81 // CHECK: [ B2 (live expressions at block exit) ] 82 // CHECK-EMPTY: 83 // CHECK-EMPTY: 84 // CHECK: [ B3 (live expressions at block exit) ] 85 // CHECK-EMPTY: 86 // CHECK-EMPTY: 87 // CHECK: [ B4 (live expressions at block exit) ] 88 // CHECK-EMPTY: 89 // CHECK-EMPTY: 90 // CHECK: [ B5 (live expressions at block exit) ] 91 // CHECK-EMPTY: 92 // CHECK-EMPTY: 93 94 95 void testWhileBodyExpression(bool flag) { 96 // No expressions should be carried over from one block to another here. 97 while (flag) { 98 int e = 1; 99 while (coin()) 100 e; 101 } 102 } 103 // CHECK: [ B0 (live expressions at block exit) ] 104 // CHECK-EMPTY: 105 // CHECK-EMPTY: 106 // CHECK: [ B1 (live expressions at block exit) ] 107 // CHECK-EMPTY: 108 // CHECK-EMPTY: 109 // CHECK: [ B2 (live expressions at block exit) ] 110 // CHECK-EMPTY: 111 // CHECK-EMPTY: 112 // CHECK: [ B3 (live expressions at block exit) ] 113 // CHECK-EMPTY: 114 // CHECK-EMPTY: 115 // CHECK: [ B4 (live expressions at block exit) ] 116 // CHECK-EMPTY: 117 // CHECK-EMPTY: 118 // CHECK: [ B5 (live expressions at block exit) ] 119 // CHECK-EMPTY: 120 // CHECK-EMPTY: 121 122 123 void testDoWhileBodyExpression(bool flag) { 124 // No expressions should be carried over from one block to another here. 125 while (flag) { 126 int e = 1; 127 do 128 e; 129 while (coin()); 130 } 131 } 132 // CHECK: [ B0 (live expressions at block exit) ] 133 // CHECK-EMPTY: 134 // CHECK-EMPTY: 135 // CHECK: [ B1 (live expressions at block exit) ] 136 // CHECK-EMPTY: 137 // CHECK-EMPTY: 138 // CHECK: [ B2 (live expressions at block exit) ] 139 // CHECK-EMPTY: 140 // CHECK-EMPTY: 141 // CHECK: [ B3 (live expressions at block exit) ] 142 // CHECK-EMPTY: 143 // CHECK-EMPTY: 144 // CHECK: [ B4 (live expressions at block exit) ] 145 // CHECK-EMPTY: 146 // CHECK-EMPTY: 147 // CHECK: [ B5 (live expressions at block exit) ] 148 // CHECK-EMPTY: 149 // CHECK-EMPTY: 150 151 152 void testForBodyExpression(bool flag) { 153 // No expressions should be carried over from one block to another here. 154 while (flag) { 155 int e = 1; 156 for (; coin();) 157 e; 158 } 159 } 160 // CHECK: [ B0 (live expressions at block exit) ] 161 // CHECK-EMPTY: 162 // CHECK-EMPTY: 163 // CHECK: [ B1 (live expressions at block exit) ] 164 // CHECK-EMPTY: 165 // CHECK-EMPTY: 166 // CHECK: [ B2 (live expressions at block exit) ] 167 // CHECK-EMPTY: 168 // CHECK-EMPTY: 169 // CHECK: [ B3 (live expressions at block exit) ] 170 // CHECK-EMPTY: 171 // CHECK-EMPTY: 172 // CHECK: [ B4 (live expressions at block exit) ] 173 // CHECK-EMPTY: 174 // CHECK-EMPTY: 175 // CHECK: [ B5 (live expressions at block exit) ] 176 // CHECK-EMPTY: 177 // CHECK-EMPTY: 178 179 void clang_analyzer_eval(bool); 180 181 void test_lambda_refcapture() { 182 int a = 6; 183 [&](int &a) { a = 42; }(a); 184 clang_analyzer_eval(a == 42); // expected-warning{{TRUE}} 185 } 186 187 // CHECK: [ B0 (live expressions at block exit) ] 188 // CHECK-EMPTY: 189 // CHECK-EMPTY: 190 // CHECK-NEXT: [ B1 (live expressions at block exit) ] 191 // CHECK-EMPTY: 192 // CHECK-EMPTY: 193 // CHECK-NEXT: [ B2 (live expressions at block exit) ] 194 // CHECK-EMPTY: 195 // CHECK-EMPTY: 196