blob: 32a4d3bef46575eff765cd4b100b21d66c373852 [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 Rosea0e6e6d2013-02-26 01:21:21 +000021 return Trivial(42); // expected-warning {{Address of stack memory associated with temporary object of type '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 Rosea0e6e6d2013-02-26 01:21:21 +000030 return NonTrivial(42); // expected-warning {{Address of stack memory associated with temporary object of type '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
Jordan Rose5e5440b2013-02-22 01:51:15 +000046 void testImmediate() {
Jordan Rose9f1d5412013-02-21 23:57:17 +000047 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 }
Jordan Rose5e5440b2013-02-22 01:51:15 +000055
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 }
Jordan Rose9f1d5412013-02-21 23:57:17 +000063}
64
Jordan Roseeafb5c62013-02-26 01:21:27 +000065namespace 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