temporaries.cpp revision 9f1d541ef1aca8f953e5bb4e7177969f0a2062d5
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 'const struct 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 'const struct 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 test() { 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 57