• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w %s
2 
3 extern bool clang_analyzer_eval(bool);
4 
5 struct Trivial {
TrivialTrivial6   Trivial(int x) : value(x) {}
7   int value;
8 };
9 
10 struct NonTrivial : public Trivial {
NonTrivialNonTrivial11   NonTrivial(int x) : Trivial(x) {}
12   ~NonTrivial();
13 };
14 
15 
getTrivial()16 Trivial getTrivial() {
17   return Trivial(42); // no-warning
18 }
19 
getTrivialRef()20 const 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 
getNonTrivial()25 NonTrivial getNonTrivial() {
26   return NonTrivial(42); // no-warning
27 }
28 
getNonTrivialRef()29 const NonTrivial &getNonTrivialRef() {
30   return NonTrivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'NonTrivial' returned to caller}}
31 }
32 
33 namespace rdar13265460 {
34   struct TrivialSubclass : public Trivial {
TrivialSubclassrdar13265460::TrivialSubclass35     TrivialSubclass(int x) : Trivial(x), anotherValue(-x) {}
36     int anotherValue;
37   };
38 
getTrivialSub()39   TrivialSubclass getTrivialSub() {
40     TrivialSubclass obj(1);
41     obj.value = 42;
42     obj.anotherValue = -42;
43     return obj;
44   }
45 
testImmediate()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 
testMaterializeTemporaryExpr()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 
65 namespace rdar13281951 {
66   struct Derived : public Trivial {
Derivedrdar13281951::Derived67     Derived(int value) : Trivial(value), value2(-value) {}
68     int value2;
69   };
70 
test()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