diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-27 04:19:56 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-27 04:19:56 +0000 |
commit | 6a6a4bbdd4230a3a4c5630888452940a0006d546 (patch) | |
tree | ef18778ccc28c7d552a68e78606d2f83261ea717 /clang/test/SemaCXX/conditional-expr.cpp | |
parent | 3bb1de7885fd065668d3eeecd73c91157286fcd6 (diff) | |
download | bcm5719-llvm-6a6a4bbdd4230a3a4c5630888452940a0006d546.tar.gz bcm5719-llvm-6a6a4bbdd4230a3a4c5630888452940a0006d546.zip |
PR17052 / DR1560 (+DR1550): In a conditional expression between a glvalue and a
throw-expression, the result is also a glvalue and isn't unnecessarily coerced
to a prvalue.
llvm-svn: 200189
Diffstat (limited to 'clang/test/SemaCXX/conditional-expr.cpp')
-rw-r--r-- | clang/test/SemaCXX/conditional-expr.cpp | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/clang/test/SemaCXX/conditional-expr.cpp b/clang/test/SemaCXX/conditional-expr.cpp index 5abee4a3c4f..538de5847de 100644 --- a/clang/test/SemaCXX/conditional-expr.cpp +++ b/clang/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; } + }; +} |