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