1// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fcxx-exceptions %s -verify -std=c++1y
2
3// Stub out types for 'typeid' to work.
4namespace std { class type_info {}; }
5
6int test1_aux(int &x);
7int test1() {
8  int x;
9  test1_aux(x);
10  return x; // no-warning
11}
12
13int test2_aux() {
14  int x;
15  int &y = x;
16  return x; // no-warning
17}
18
19// Don't warn on unevaluated contexts.
20void unevaluated_tests() {
21  int x;
22  (void)sizeof(x);
23  (void)typeid(x);
24}
25
26// Warn for glvalue arguments to typeid whose type is polymorphic.
27struct A { virtual ~A() {} };
28void polymorphic_test() {
29  A *a; // expected-note{{initialize the variable 'a' to silence this warning}}
30  (void)typeid(*a); // expected-warning{{variable 'a' is uninitialized when used here}}
31}
32
33// Handle cases where the CFG may constant fold some branches, thus
34// mitigating the need for some path-sensitivity in the analysis.
35unsigned test3_aux();
36unsigned test3() {
37  unsigned x = 0;
38  const bool flag = true;
39  if (flag && (x = test3_aux()) == 0) {
40    return x;
41  }
42  return x;
43}
44unsigned test3_b() {
45  unsigned x ;
46  const bool flag = true;
47  if (flag && (x = test3_aux()) == 0) {
48    x = 1;
49  }
50  return x; // no-warning
51}
52unsigned test3_c() {
53  unsigned x; // expected-note{{initialize the variable 'x' to silence this warning}}
54  const bool flag = false;
55  if (flag && (x = test3_aux()) == 0) {
56    x = 1;
57  }
58  return x; // expected-warning{{variable 'x' is uninitialized when used here}}
59}
60
61enum test4_A {
62 test4_A_a, test_4_A_b
63};
64test4_A test4() {
65 test4_A a; // expected-note{{variable 'a' is declared here}}
66 return a; // expected-warning{{variable 'a' is uninitialized when used here}}
67}
68
69// Test variables getting invalidated by function calls with reference arguments
70// *AND* there are multiple invalidated arguments.
71void test5_aux(int &, int &);
72
73int test5() {
74  int x, y;
75  test5_aux(x, y);
76  return x + y; // no-warning
77}
78
79// This test previously crashed Sema.
80class Rdar9188004A {
81public:
82  virtual ~Rdar9188004A();
83};
84
85template< typename T > class Rdar9188004B : public Rdar9188004A {
86virtual double *foo(Rdar9188004B *next) const  {
87    double *values = next->foo(0);
88    try {
89    }
90    catch(double e) {
91      values[0] = e;
92    }
93    return 0;
94  }
95};
96class Rdar9188004C : public Rdar9188004B<Rdar9188004A> {
97  virtual void bar(void) const;
98};
99void Rdar9188004C::bar(void) const {}
100
101// Don't warn about uninitialized variables in unreachable code.
102void PR9625() {
103  if (false) {
104    int x;
105    (void)static_cast<float>(x); // no-warning
106  }
107}
108
109// Don't warn about variables declared in "catch"
110void RDar9251392_bar(const char *msg);
111
112void RDar9251392() {
113  try {
114    throw "hi";
115  }
116  catch (const char* msg) {
117    RDar9251392_bar(msg); // no-warning
118  }
119}
120
121// Test handling of "no-op" casts.
122void test_noop_cast()
123{
124    int x = 1;
125    int y = (int&)x; // no-warning
126}
127
128void test_noop_cast2() {
129    int x; // expected-note {{initialize the variable 'x' to silence this warning}}
130    int y = (int&)x; // expected-warning {{uninitialized when used here}}
131}
132
133// Test handling of bit casts.
134void test_bitcasts() {
135  int x = 1;
136  int y = (float &)x; // no-warning
137}
138
139void test_bitcasts_2() {
140  int x;  // expected-note {{initialize the variable 'x' to silence this warning}}
141  int y = (float &)x; // expected-warning {{uninitialized when used here}}
142}
143
144void consume_const_ref(const int &n);
145int test_const_ref() {
146  int n; // expected-note {{variable}}
147  consume_const_ref(n);
148  return n; // expected-warning {{uninitialized when used here}}
149}
150
151// Don't crash here.
152auto PR19996 = [a=0]{int t; return a;};
153