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