blob: 8d0dd6e04c9c2a33ba8d305b9dbdce82f9dbebeb [file] [log] [blame]
Anna Zaksbfa9ab82013-01-24 23:15:30 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w %s
Jordan Rose73212df2012-08-29 01:11:59 +00002
Jordan Rose9f1d5412013-02-21 23:57:17 +00003extern bool clang_analyzer_eval(bool);
4
Jordan Rose73212df2012-08-29 01:11:59 +00005struct 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() {
Jordan Rosebc403862013-02-15 00:32:15 +000021 return Trivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'const struct Trivial' returned to caller}}
Jordan Rose73212df2012-08-29 01:11:59 +000022}
23
24
25NonTrivial getNonTrivial() {
26 return NonTrivial(42); // no-warning
27}
28
29const NonTrivial &getNonTrivialRef() {
Jordan Rosebc403862013-02-15 00:32:15 +000030 return NonTrivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'const struct NonTrivial' returned to caller}}
Jordan Rose73212df2012-08-29 01:11:59 +000031}
32
Jordan Rose9f1d5412013-02-21 23:57:17 +000033namespace 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