conditional-expr.cpp revision b70cf44bf1b1956e0c6b98373c4f69b23afa0052
1// RUN: %clang_cc1 -fsyntax-only -verify -faccess-control -std=c++0x -Wsign-compare %s
2
3// C++ rules for ?: are a lot stricter than C rules, and have to take into
4// account more conversion options.
5// This test runs in C++0x mode for the contextual conversion of the condition.
6
7struct ToBool { explicit operator bool(); };
8
9struct B;
10struct A { A(); A(const B&); }; // expected-note 2 {{candidate constructor}} \
11               // expected-note 2 {{candidate is the implicit copy constructor}}
12struct B { operator A() const; }; // expected-note 2 {{candidate function}}
13struct I { operator int(); };
14struct J { operator I(); };
15struct K { operator double(); };
16typedef void (*vfn)();
17struct F { operator vfn(); };
18struct G { operator vfn(); };
19
20struct Base {
21  int trick();
22  A trick() const;
23  void fn1();
24};
25struct Derived : Base {
26  void fn2();
27};
28struct Convertible { operator Base&(); };
29struct Priv : private Base {}; // expected-note 4 {{declared private here}}
30struct Mid : Base {};
31struct Fin : Mid, Derived {};
32typedef void (Derived::*DFnPtr)();
33struct ToMemPtr { operator DFnPtr(); };
34
35struct BadDerived;
36struct BadBase { operator BadDerived&(); };
37struct BadDerived : BadBase {};
38
39struct Fields {
40  int i1, i2, b1 : 3, b2 : 3;
41};
42struct MixedFields {
43  int i;
44  volatile int vi;
45  const int ci;
46  const volatile int cvi;
47};
48struct MixedFieldsDerived : MixedFields {
49};
50
51enum Enum { EVal };
52
53struct Ambig {
54  operator short(); // expected-note 2 {{candidate function}}
55  operator signed char(); // expected-note 2 {{candidate function}}
56};
57
58void test()
59{
60  // This function tests C++0x 5.16
61
62  // p1 (contextually convert to bool)
63  int i1 = ToBool() ? 0 : 1;
64
65  // p2 (one or both void, and throwing)
66  i1 ? throw 0 : throw 1;
67  i1 ? test() : throw 1;
68  i1 ? throw 0 : test();
69  i1 ? test() : test();
70  i1 = i1 ? throw 0 : 0;
71  i1 = i1 ? 0 : throw 0;
72  i1 ? 0 : test(); // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
73  i1 ? test() : 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
74  (i1 ? throw 0 : i1) = 0; // expected-error {{expression is not assignable}}
75  (i1 ? i1 : throw 0) = 0; // expected-error {{expression is not assignable}}
76
77  // p3 (one or both class type, convert to each other)
78  // b1 (lvalues)
79  Base base;
80  Derived derived;
81  Convertible conv;
82  Base &bar1 = i1 ? base : derived;
83  Base &bar2 = i1 ? derived : base;
84  Base &bar3 = i1 ? base : conv;
85  Base &bar4 = i1 ? conv : base;
86  // these are ambiguous
87  BadBase bb;
88  BadDerived bd;
89  (void)(i1 ? bb : bd); // expected-error {{conditional expression is ambiguous; 'BadBase' can be converted to 'BadDerived' and vice versa}}
90  (void)(i1 ? bd : bb); // expected-error {{conditional expression is ambiguous}}
91  // curiously enough (and a defect?), these are not
92  // for rvalues, hierarchy takes precedence over other conversions
93  (void)(i1 ? BadBase() : BadDerived());
94  (void)(i1 ? BadDerived() : BadBase());
95
96  // b2.1 (hierarchy stuff)
97  const Base constret();
98  const Derived constder();
99  // should use const overload
100  A a1((i1 ? constret() : Base()).trick());
101  A a2((i1 ? Base() : constret()).trick());
102  A a3((i1 ? constret() : Derived()).trick());
103  A a4((i1 ? Derived() : constret()).trick());
104  // should use non-const overload
105  i1 = (i1 ? Base() : Base()).trick();
106  i1 = (i1 ? Base() : Base()).trick();
107  i1 = (i1 ? Base() : Derived()).trick();
108  i1 = (i1 ? Derived() : Base()).trick();
109  // should fail: const lost
110  (void)(i1 ? Base() : constder()); // expected-error {{incompatible operand types ('Base' and 'Derived const')}}
111  (void)(i1 ? constder() : Base()); // expected-error {{incompatible operand types ('Derived const' and 'Base')}}
112
113  Priv priv;
114  Fin fin;
115  (void)(i1 ? Base() : Priv()); // expected-error{{private base class}}
116  (void)(i1 ? Priv() : Base()); // expected-error{{private base class}}
117  (void)(i1 ? Base() : Fin()); // expected-error{{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
118  (void)(i1 ? Fin() : Base()); // expected-error{{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
119  (void)(i1 ? base : priv); // expected-error {{private base class}}
120  (void)(i1 ? priv : base); // expected-error {{private base class}}
121  (void)(i1 ? base : fin); // expected-error {{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
122  (void)(i1 ? fin : base); // expected-error {{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
123
124  // b2.2 (non-hierarchy)
125  i1 = i1 ? I() : i1;
126  i1 = i1 ? i1 : I();
127  I i2(i1 ? I() : J());
128  I i3(i1 ? J() : I());
129  // "the type [it] woud have if E2 were converted to an rvalue"
130  vfn pfn = i1 ? F() : test;
131  pfn = i1 ? test : F();
132  (void)(i1 ? A() : B()); // expected-error {{conversion from 'B' to 'A' is ambiguous}}
133  (void)(i1 ? B() : A()); // expected-error {{conversion from 'B' to 'A' is ambiguous}}
134  (void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}}
135  (void)(i1 ? Ambig() : 1); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}}
136  // By the way, this isn't an lvalue:
137  &(i1 ? i1 : i2); // expected-error {{address expression must be an lvalue or a function designator}}
138
139  // p4 (lvalue, same type)
140  Fields flds;
141  int &ir1 = i1 ? flds.i1 : flds.i2;
142  (i1 ? flds.b1 : flds.i2) = 0;
143  (i1 ? flds.i1 : flds.b2) = 0;
144  (i1 ? flds.b1 : flds.b2) = 0;
145
146  // p5 (conversion to built-in types)
147  // GCC 4.3 fails these
148  double d1 = i1 ? I() : K();
149  pfn = i1 ? F() : G();
150  DFnPtr pfm;
151  pfm = i1 ? DFnPtr() : &Base::fn1;
152  pfm = i1 ? &Base::fn1 : DFnPtr();
153
154  // p6 (final conversions)
155  i1 = i1 ? i1 : ir1;
156  int *pi1 = i1 ? &i1 : 0;
157  pi1 = i1 ? 0 : &i1;
158  i1 = i1 ? i1 : EVal;
159  i1 = i1 ? EVal : i1;
160  d1 = i1 ? 'c' : 4.0;
161  d1 = i1 ? 4.0 : 'c';
162  Base *pb = i1 ? (Base*)0 : (Derived*)0;
163  pb = i1 ? (Derived*)0 : (Base*)0;
164  pfm = i1 ? &Base::fn1 : &Derived::fn2;
165  pfm = i1 ? &Derived::fn2 : &Base::fn1;
166  pfm = i1 ? &Derived::fn2 : 0;
167  pfm = i1 ? 0 : &Derived::fn2;
168  const int (MixedFieldsDerived::*mp1) =
169    i1 ? &MixedFields::ci : &MixedFieldsDerived::i;
170  const volatile int (MixedFields::*mp2) =
171    i1 ? &MixedFields::ci : &MixedFields::cvi;
172  (void)(i1 ? &MixedFields::ci : &MixedFields::vi);
173  // Conversion of primitives does not result in an lvalue.
174  &(i1 ? i1 : d1); // expected-error {{address expression must be an lvalue or a function designator}}
175
176  (void)&(i1 ? flds.b1 : flds.i1); // expected-error {{address of bit-field requested}}
177  (void)&(i1 ? flds.i1 : flds.b1); // expected-error {{address of bit-field requested}}
178
179
180  unsigned long test0 = 5;
181  test0 = test0 ? (long) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
182  test0 = test0 ? (int) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
183  test0 = test0 ? (short) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
184  test0 = test0 ? test0 : (long) test0; // expected-warning {{operands of ? are integers of different signs}}
185  test0 = test0 ? test0 : (int) test0; // expected-warning {{operands of ? are integers of different signs}}
186  test0 = test0 ? test0 : (short) test0; // expected-warning {{operands of ? are integers of different signs}}
187  test0 = test0 ? test0 : (long) 10;
188  test0 = test0 ? test0 : (int) 10;
189  test0 = test0 ? test0 : (short) 10;
190  test0 = test0 ? (long) 10 : test0;
191  test0 = test0 ? (int) 10 : test0;
192  test0 = test0 ? (short) 10 : test0;
193
194  test0 = test0 ? EVal : test0;
195  test0 = test0 ? EVal : (int) test0;
196
197  // Note the thing that this does not test: since DR446, various situations
198  // *must* create a separate temporary copy of class objects. This can only
199  // be properly tested at runtime, though.
200}
201