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