1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s -Wno-undefined-bool-conversion 2*67e74705SXin Li 3*67e74705SXin Li typedef __INTPTR_TYPE__ intptr_t; 4*67e74705SXin Li g()5*67e74705SXin Liconst int& g() { 6*67e74705SXin Li int s; 7*67e74705SXin Li return s; // expected-warning{{Address of stack memory associated with local variable 's' returned}} expected-warning{{reference to stack memory associated with local variable 's' returned}} 8*67e74705SXin Li } 9*67e74705SXin Li g2()10*67e74705SXin Liconst int& g2() { 11*67e74705SXin Li int s1; 12*67e74705SXin Li int &s2 = s1; // expected-note {{binding reference variable 's2' here}} 13*67e74705SXin Li return s2; // expected-warning{{Address of stack memory associated with local variable 's1' returned}} expected-warning {{reference to stack memory associated with local variable 's1' returned}} 14*67e74705SXin Li } 15*67e74705SXin Li g3()16*67e74705SXin Liconst int& g3() { 17*67e74705SXin Li int s1; 18*67e74705SXin Li int &s2 = s1; // expected-note {{binding reference variable 's2' here}} 19*67e74705SXin Li int &s3 = s2; // expected-note {{binding reference variable 's3' here}} 20*67e74705SXin Li return s3; // expected-warning{{Address of stack memory associated with local variable 's1' returned}} expected-warning {{reference to stack memory associated with local variable 's1' returned}} 21*67e74705SXin Li } 22*67e74705SXin Li g4()23*67e74705SXin Livoid g4() { 24*67e74705SXin Li static const int &x = 3; // no warning 25*67e74705SXin Li } 26*67e74705SXin Li 27*67e74705SXin Li int get_value(); 28*67e74705SXin Li get_reference1()29*67e74705SXin Liconst int &get_reference1() { return get_value(); } // expected-warning{{Address of stack memory associated with temporary object of type 'int' returned}} expected-warning {{returning reference to local temporary}} 30*67e74705SXin Li get_reference2()31*67e74705SXin Liconst int &get_reference2() { 32*67e74705SXin Li const int &x = get_value(); // expected-note {{binding reference variable 'x' here}} 33*67e74705SXin Li return x; // expected-warning{{Address of stack memory associated with temporary object of type 'int' returned}} expected-warning {{returning reference to local temporary}} 34*67e74705SXin Li } 35*67e74705SXin Li get_reference3()36*67e74705SXin Liconst int &get_reference3() { 37*67e74705SXin Li const int &x1 = get_value(); // expected-note {{binding reference variable 'x1' here}} 38*67e74705SXin Li const int &x2 = x1; // expected-note {{binding reference variable 'x2' here}} 39*67e74705SXin Li return x2; // expected-warning{{Address of stack memory associated with temporary object of type 'int' returned}} expected-warning {{returning reference to local temporary}} 40*67e74705SXin Li } 41*67e74705SXin Li 42*67e74705SXin Li int global_var; f1()43*67e74705SXin Liint *f1() { 44*67e74705SXin Li int &y = global_var; 45*67e74705SXin Li return &y; 46*67e74705SXin Li } 47*67e74705SXin Li f2()48*67e74705SXin Liint *f2() { 49*67e74705SXin Li int x1; 50*67e74705SXin Li int &x2 = x1; // expected-note {{binding reference variable 'x2' here}} 51*67e74705SXin Li return &x2; // expected-warning{{Address of stack memory associated with local variable 'x1' returned}} expected-warning {{address of stack memory associated with local variable 'x1' returned}} 52*67e74705SXin Li } 53*67e74705SXin Li f3()54*67e74705SXin Liint *f3() { 55*67e74705SXin Li int x1; 56*67e74705SXin Li int *const &x2 = &x1; // expected-note {{binding reference variable 'x2' here}} 57*67e74705SXin Li return x2; // expected-warning {{address of stack memory associated with local variable 'x1' returned}} expected-warning {{Address of stack memory associated with local variable 'x1' returned to caller}} 58*67e74705SXin Li } 59*67e74705SXin Li f4()60*67e74705SXin Liconst int *f4() { 61*67e74705SXin Li const int &x1 = get_value(); // expected-note {{binding reference variable 'x1' here}} 62*67e74705SXin Li const int &x2 = x1; // expected-note {{binding reference variable 'x2' here}} 63*67e74705SXin Li return &x2; // expected-warning{{Address of stack memory associated with temporary object of type 'int' returned}} expected-warning {{returning address of local temporary}} 64*67e74705SXin Li } 65*67e74705SXin Li 66*67e74705SXin Li struct S { 67*67e74705SXin Li int x; 68*67e74705SXin Li }; 69*67e74705SXin Li mf()70*67e74705SXin Liint *mf() { 71*67e74705SXin Li S s1; 72*67e74705SXin Li S &s2 = s1; // expected-note {{binding reference variable 's2' here}} 73*67e74705SXin Li int &x = s2.x; // expected-note {{binding reference variable 'x' here}} 74*67e74705SXin Li return &x; // expected-warning{{Address of stack memory associated with local variable 's1' returned}} expected-warning {{address of stack memory associated with local variable 's1' returned}} 75*67e74705SXin Li } 76*67e74705SXin Li lf()77*67e74705SXin Livoid *lf() { 78*67e74705SXin Li label: 79*67e74705SXin Li void *const &x = &&label; // expected-note {{binding reference variable 'x' here}} 80*67e74705SXin Li return x; // expected-warning {{returning address of label, which is local}} 81*67e74705SXin Li } 82*67e74705SXin Li 83*67e74705SXin Li template <typename T> 84*67e74705SXin Li struct TS { 85*67e74705SXin Li int *get(); mTS86*67e74705SXin Li int *m() { 87*67e74705SXin Li int *&x = get(); 88*67e74705SXin Li return x; 89*67e74705SXin Li } 90*67e74705SXin Li }; 91*67e74705SXin Li 92*67e74705SXin Li // rdar://11345441 f5()93*67e74705SXin Liint* f5() { 94*67e74705SXin Li int& i = i; // expected-warning {{Assigned value is garbage or undefined}} expected-note {{binding reference variable 'i' here}} expected-warning{{reference 'i' is not yet bound to a value when used within its own initialization}} 95*67e74705SXin Li return &i; // expected-warning {{address of stack memory associated with local variable 'i' returned}} 96*67e74705SXin Li } 97*67e74705SXin Li radar13226577()98*67e74705SXin Livoid *radar13226577() { 99*67e74705SXin Li void *p = &p; 100*67e74705SXin Li return p; // expected-warning {{stack memory associated with local variable 'p' returned to caller}} 101*67e74705SXin Li } 102*67e74705SXin Li 103*67e74705SXin Li namespace rdar13296133 { 104*67e74705SXin Li class ConvertsToBool { 105*67e74705SXin Li public: operator bool() const106*67e74705SXin Li operator bool() const { return this; } 107*67e74705SXin Li }; 108*67e74705SXin Li 109*67e74705SXin Li class ConvertsToIntptr { 110*67e74705SXin Li public: operator intptr_t() const111*67e74705SXin Li operator intptr_t() const { return reinterpret_cast<intptr_t>(this); } 112*67e74705SXin Li }; 113*67e74705SXin Li 114*67e74705SXin Li class ConvertsToPointer { 115*67e74705SXin Li public: operator const void*() const116*67e74705SXin Li operator const void *() const { return this; } 117*67e74705SXin Li }; 118*67e74705SXin Li returnAsNonLoc()119*67e74705SXin Li intptr_t returnAsNonLoc() { 120*67e74705SXin Li ConvertsToIntptr obj; 121*67e74705SXin Li return obj; // expected-warning{{Address of stack memory associated with local variable 'obj' returned to caller}} 122*67e74705SXin Li } 123*67e74705SXin Li returnAsBool()124*67e74705SXin Li bool returnAsBool() { 125*67e74705SXin Li ConvertsToBool obj; 126*67e74705SXin Li return obj; // no-warning 127*67e74705SXin Li } 128*67e74705SXin Li returnAsNonLocViaPointer()129*67e74705SXin Li intptr_t returnAsNonLocViaPointer() { 130*67e74705SXin Li ConvertsToPointer obj; 131*67e74705SXin Li return reinterpret_cast<intptr_t>(static_cast<const void *>(obj)); // expected-warning{{Address of stack memory associated with local variable 'obj' returned to caller}} 132*67e74705SXin Li } 133*67e74705SXin Li returnAsBoolViaPointer()134*67e74705SXin Li bool returnAsBoolViaPointer() { 135*67e74705SXin Li ConvertsToPointer obj; 136*67e74705SXin Li return obj; // no-warning 137*67e74705SXin Li } 138*67e74705SXin Li } 139*67e74705SXin Li 140