aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/conditional-expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX/conditional-expr.cpp')
-rw-r--r--test/SemaCXX/conditional-expr.cpp27
1 files changed, 22 insertions, 5 deletions
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index 5abee4a3c4f8..538de5847de8 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -75,6 +75,7 @@ void test()
int i1 = ToBool() ? 0 : 1;
// p2 (one or both void, and throwing)
+ Fields flds;
i1 ? throw 0 : throw 1;
i1 ? test() : throw 1;
i1 ? throw 0 : test();
@@ -85,8 +86,16 @@ void test()
i1 = i1 ? 0 : (throw 0);
i1 ? 0 : test(); // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
i1 ? test() : 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
- (i1 ? throw 0 : i1) = 0; // expected-error {{expression is not assignable}}
- (i1 ? i1 : throw 0) = 0; // expected-error {{expression is not assignable}}
+ (i1 ? throw 0 : i1) = 0;
+ (i1 ? i1 : throw 0) = 0;
+ (i1 ? (throw 0) : i1) = 0;
+ (i1 ? i1 : (throw 0)) = 0;
+ (i1 ? (void)(throw 0) : i1) = 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
+ (i1 ? i1 : (void)(throw 0)) = 0; // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
+ int &throwRef1 = (i1 ? flds.i1 : throw 0);
+ int &throwRef2 = (i1 ? throw 0 : flds.i1);
+ int &throwRef3 = (i1 ? flds.b1 : throw 0); // expected-error {{non-const reference cannot bind to bit-field}}
+ int &throwRef4 = (i1 ? throw 0 : flds.b1); // expected-error {{non-const reference cannot bind to bit-field}}
// p3 (one or both class type, convert to each other)
// b1 (lvalues)
@@ -151,7 +160,6 @@ void test()
&(i1 ? i1 : i2); // expected-error {{cannot take the address of an rvalue}}
// p4 (lvalue, same type)
- Fields flds;
int &ir1 = i1 ? flds.i1 : flds.i2;
(i1 ? flds.b1 : flds.i2) = 0;
(i1 ? flds.i1 : flds.b2) = 0;
@@ -219,8 +227,8 @@ void test()
// *must* create a separate temporary copy of class objects. This can only
// be properly tested at runtime, though.
- const Abstract &a = true ? static_cast<const Abstract&>(Derived1()) : Derived2(); // expected-error {{allocating an object of abstract class type 'const Abstract'}}
- true ? static_cast<const Abstract&>(Derived1()) : throw 3; // expected-error {{allocating an object of abstract class type 'const Abstract'}}
+ const Abstract &abstract1 = true ? static_cast<const Abstract&>(Derived1()) : Derived2(); // expected-error {{allocating an object of abstract class type 'const Abstract'}}
+ const Abstract &abstract2 = true ? static_cast<const Abstract&>(Derived1()) : throw 3; // ok
}
namespace PR6595 {
@@ -367,3 +375,12 @@ namespace DR587 {
const volatile int &cvir2 = b ? cvi : vi;
const volatile int &cvir3 = b ? ci : vi; // expected-error{{volatile lvalue reference to type 'const volatile int' cannot bind to a temporary of type 'int'}}
}
+
+namespace PR17052 {
+ struct X {
+ int i_;
+ bool b_;
+
+ int &test() { return b_ ? i_ : throw 1; }
+ };
+}