1// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w %s 2 3extern bool clang_analyzer_eval(bool); 4 5struct Trivial { 6 Trivial(int x) : value(x) {} 7 int value; 8}; 9 10struct NonTrivial : public Trivial { 11 NonTrivial(int x) : Trivial(x) {} 12 ~NonTrivial(); 13}; 14 15 16Trivial getTrivial() { 17 return Trivial(42); // no-warning 18} 19 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 25NonTrivial getNonTrivial() { 26 return NonTrivial(42); // no-warning 27} 28 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 33namespace rdar13265460 { 34 struct TrivialSubclass : public Trivial { 35 TrivialSubclass(int x) : Trivial(x), anotherValue(-x) {} 36 int anotherValue; 37 }; 38 39 TrivialSubclass getTrivialSub() { 40 TrivialSubclass obj(1); 41 obj.value = 42; 42 obj.anotherValue = -42; 43 return obj; 44 } 45 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 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 65namespace rdar13281951 { 66 struct Derived : public Trivial { 67 Derived(int value) : Trivial(value), value2(-value) {} 68 int value2; 69 }; 70 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