1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w %s 2 3 extern bool clang_analyzer_eval(bool); 4 5 struct Trivial { TrivialTrivial6 Trivial(int x) : value(x) {} 7 int value; 8 }; 9 10 struct NonTrivial : public Trivial { NonTrivialNonTrivial11 NonTrivial(int x) : Trivial(x) {} 12 ~NonTrivial(); 13 }; 14 15 getTrivial()16Trivial getTrivial() { 17 return Trivial(42); // no-warning 18 } 19 getTrivialRef()20const Trivial &getTrivialRef() { 21 return Trivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'Trivial' returned to caller}} 22 } 23 24 getNonTrivial()25NonTrivial getNonTrivial() { 26 return NonTrivial(42); // no-warning 27 } 28 getNonTrivialRef()29const NonTrivial &getNonTrivialRef() { 30 return NonTrivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'NonTrivial' returned to caller}} 31 } 32 33 namespace rdar13265460 { 34 struct TrivialSubclass : public Trivial { TrivialSubclassrdar13265460::TrivialSubclass35 TrivialSubclass(int x) : Trivial(x), anotherValue(-x) {} 36 int anotherValue; 37 }; 38 getTrivialSub()39 TrivialSubclass getTrivialSub() { 40 TrivialSubclass obj(1); 41 obj.value = 42; 42 obj.anotherValue = -42; 43 return obj; 44 } 45 testImmediate()46 void testImmediate() { 47 TrivialSubclass obj = getTrivialSub(); 48 49 clang_analyzer_eval(obj.value == 42); // expected-warning{{TRUE}} 50 clang_analyzer_eval(obj.anotherValue == -42); // expected-warning{{TRUE}} 51 52 clang_analyzer_eval(getTrivialSub().value == 42); // expected-warning{{TRUE}} 53 clang_analyzer_eval(getTrivialSub().anotherValue == -42); // expected-warning{{TRUE}} 54 } 55 testMaterializeTemporaryExpr()56 void testMaterializeTemporaryExpr() { 57 const TrivialSubclass &ref = getTrivialSub(); 58 clang_analyzer_eval(ref.value == 42); // expected-warning{{TRUE}} 59 60 const Trivial &baseRef = getTrivialSub(); 61 clang_analyzer_eval(baseRef.value == 42); // expected-warning{{TRUE}} 62 } 63 } 64 65 namespace rdar13281951 { 66 struct Derived : public Trivial { Derivedrdar13281951::Derived67 Derived(int value) : Trivial(value), value2(-value) {} 68 int value2; 69 }; 70 test()71 void test() { 72 Derived obj(1); 73 obj.value = 42; 74 const Trivial * const &pointerRef = &obj; 75 clang_analyzer_eval(pointerRef->value == 42); // expected-warning{{TRUE}} 76 } 77 } 78 79