1*67e74705SXin Li// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core -verify %s 2*67e74705SXin Li 3*67e74705SXin Listruct s { 4*67e74705SXin Li int data; 5*67e74705SXin Li}; 6*67e74705SXin Li 7*67e74705SXin Listruct s global; 8*67e74705SXin Li 9*67e74705SXin Livoid g(int); 10*67e74705SXin Li 11*67e74705SXin Livoid f4() { 12*67e74705SXin Li int a; 13*67e74705SXin Li if (global.data == 0) 14*67e74705SXin Li a = 3; 15*67e74705SXin Li if (global.data == 0) // When the true branch is feasible 'a = 3'. 16*67e74705SXin Li g(a); // no-warning 17*67e74705SXin Li} 18*67e74705SXin Li 19*67e74705SXin Li 20*67e74705SXin Li// Test uninitialized value due to part of the structure being uninitialized. 21*67e74705SXin Listruct TestUninit { int x; int y; }; 22*67e74705SXin Listruct TestUninit test_uninit_aux(); 23*67e74705SXin Livoid test_unit_aux2(int); 24*67e74705SXin Livoid test_uninit_pos() { 25*67e74705SXin Li struct TestUninit v1 = { 0, 0 }; 26*67e74705SXin Li struct TestUninit v2 = test_uninit_aux(); 27*67e74705SXin Li int z; 28*67e74705SXin Li v1.y = z; // expected-warning{{Assigned value is garbage or undefined}} 29*67e74705SXin Li test_unit_aux2(v2.x + v1.y); 30*67e74705SXin Li} 31*67e74705SXin Livoid test_uninit_pos_2() { 32*67e74705SXin Li struct TestUninit v1 = { 0, 0 }; 33*67e74705SXin Li struct TestUninit v2; 34*67e74705SXin Li test_unit_aux2(v2.x + v1.y); // expected-warning{{The left operand of '+' is a garbage value}} 35*67e74705SXin Li} 36*67e74705SXin Livoid test_uninit_pos_3() { 37*67e74705SXin Li struct TestUninit v1 = { 0, 0 }; 38*67e74705SXin Li struct TestUninit v2; 39*67e74705SXin Li test_unit_aux2(v1.y + v2.x); // expected-warning{{The right operand of '+' is a garbage value}} 40*67e74705SXin Li} 41*67e74705SXin Li 42*67e74705SXin Livoid test_uninit_neg() { 43*67e74705SXin Li struct TestUninit v1 = { 0, 0 }; 44*67e74705SXin Li struct TestUninit v2 = test_uninit_aux(); 45*67e74705SXin Li test_unit_aux2(v2.x + v1.y); 46*67e74705SXin Li} 47*67e74705SXin Li 48*67e74705SXin Liextern void test_uninit_struct_arg_aux(struct TestUninit arg); 49*67e74705SXin Livoid test_uninit_struct_arg() { 50*67e74705SXin Li struct TestUninit x; 51*67e74705SXin Li test_uninit_struct_arg_aux(x); // expected-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}} 52*67e74705SXin Li} 53*67e74705SXin Li 54*67e74705SXin Li@interface Foo 55*67e74705SXin Li- (void) passVal:(struct TestUninit)arg; 56*67e74705SXin Li@end 57*67e74705SXin Livoid testFoo(Foo *o) { 58*67e74705SXin Li struct TestUninit x; 59*67e74705SXin Li [o passVal:x]; // expected-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}} 60*67e74705SXin Li} 61*67e74705SXin Li 62*67e74705SXin Li// Test case from <rdar://problem/7780304>. That shows an uninitialized value 63*67e74705SXin Li// being used in the LHS of a compound assignment. 64*67e74705SXin Livoid rdar_7780304() { 65*67e74705SXin Li typedef struct s_r7780304 { int x; } s_r7780304; 66*67e74705SXin Li s_r7780304 b; 67*67e74705SXin Li b.x |= 1; // expected-warning{{The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage}} 68*67e74705SXin Li} 69*67e74705SXin Li 70*67e74705SXin Li 71*67e74705SXin Li// The flip side of PR10163 -- float arrays that are actually uninitialized 72*67e74705SXin Li// (The main test is in uninit-vals.m) 73*67e74705SXin Livoid test_PR10163(float); 74*67e74705SXin Livoid PR10163 (void) { 75*67e74705SXin Li float x[2]; 76*67e74705SXin Li test_PR10163(x[1]); // expected-warning{{uninitialized value}} 77*67e74705SXin Li} 78*67e74705SXin Li 79*67e74705SXin Listruct MyStr { 80*67e74705SXin Li int x; 81*67e74705SXin Li int y; 82*67e74705SXin Li}; 83*67e74705SXin Livoid swap(struct MyStr *To, struct MyStr *From) { 84*67e74705SXin Li // This is not really a swap but close enough for our test. 85*67e74705SXin Li To->x = From->x; 86*67e74705SXin Li To->y = From->y; // no warning 87*67e74705SXin Li} 88*67e74705SXin Liint test_undefined_member_assignment_in_swap(struct MyStr *s2) { 89*67e74705SXin Li struct MyStr s1; 90*67e74705SXin Li s1.x = 5; 91*67e74705SXin Li swap(s2, &s1); 92*67e74705SXin Li return s2->y; // expected-warning{{Undefined or garbage value returned to caller}} 93*67e74705SXin Li} 94