diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-09 18:49:13 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-09 18:49:13 +0000 |
| commit | b8c0f553ed6b7e52b12afa00ace3e30754482037 (patch) | |
| tree | 17b50394cbd2219fdb1717c18dc437df586b12be /clang/test | |
| parent | 0c1c3bbc78e4548831e307c0e527449254a2bbbb (diff) | |
| download | bcm5719-llvm-b8c0f553ed6b7e52b12afa00ace3e30754482037.tar.gz bcm5719-llvm-b8c0f553ed6b7e52b12afa00ace3e30754482037.zip | |
DR1295 and cleanup for P0135R1: Make our initialization code more directly
mirror the description in the standard. Per DR1295, this means that binding a
const / rvalue reference to a bit-field no longer "binds directly", and per
P0135R1, this means that we materialize a temporary in reference binding
after adjusting cv-qualifiers and before performing a derived-to-base cast.
In C++11 onwards, this should have fixed the last case where we would
materialize a temporary of the wrong type (with a subobject adjustment inside
the MaterializeTemporaryExpr instead of outside), but we still have to deal
with that possibility in C++98, unless we want to start using xvalues to
represent materialized temporaries there too.
llvm-svn: 289250
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp | 23 | ||||
| -rw-r--r-- | clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp | 4 | ||||
| -rw-r--r-- | clang/test/CXX/drs/dr12xx.cpp | 28 | ||||
| -rw-r--r-- | clang/test/SemaCXX/constant-expression-cxx11.cpp | 12 | ||||
| -rw-r--r-- | clang/test/SemaCXX/constant-expression-cxx1z.cpp | 5 | ||||
| -rw-r--r-- | clang/test/SemaCXX/member-init.cpp | 2 | ||||
| -rw-r--r-- | clang/test/SemaCXX/microsoft-new-delete.cpp | 2 | ||||
| -rw-r--r-- | clang/test/SemaCXX/reinterpret-cast.cpp | 2 |
8 files changed, 61 insertions, 17 deletions
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp index be1113d47e3..052349c8e2e 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -ast-dump %s 2>&1 | FileCheck %s -// CHECK: example0 +// CHECK-LABEL: example0 void example0() { double d = 2.0; // CHECK: VarDecl{{.*}}rd 'double &' @@ -14,14 +14,15 @@ void example0() { struct A { }; struct B : A { } b; -// CHECK: example1 +// CHECK-LABEL: example1 void example1() { // CHECK: VarDecl{{.*}}ra 'struct A &' // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)> A &ra = b; // CHECK: VarDecl{{.*}}rca 'const struct A &' - // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <NoOp> - // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)> + // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)> + // CHECK-NOT: MaterializeTemporaryExpr + // CHECK: ImplicitCastExpr{{.*}}'const struct B' lvalue <NoOp> const A& rca = b; } @@ -31,21 +32,23 @@ struct X { operator B(); } x; -// CHECK: example2 +// CHECK-LABEL: example2 void example2() { // CHECK: VarDecl{{.*}}rca 'const struct A &' - // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp> - // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)> + // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)> + // CHECK: MaterializeTemporaryExpr{{.*}}'const struct B' + // CHECK: ImplicitCastExpr{{.*}}'const struct B' <NoOp> // CHECK: CallExpr{{.*}}B const A &rca = f(); // CHECK: VarDecl{{.*}}r 'const struct A &' - // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp> - // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)> + // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)> + // CHECK: MaterializeTemporaryExpr{{.*}}'const struct B' + // CHECK: ImplicitCastExpr{{.*}}'const struct B' <NoOp> // CHECK: CXXMemberCallExpr{{.*}}'struct B' const A& r = x; } -// CHECK: example3 +// CHECK-LABEL: example3 void example3() { // CHECK: VarDecl{{.*}}rcd2 'const double &' // CHECK: ImplicitCastExpr{{.*}} <IntegralToFloating> diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp index 263f661208c..e775e8f0e3c 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp @@ -41,7 +41,7 @@ namespace PR6066 { namespace test3 { struct A { - unsigned bitX : 4; // expected-note 4 {{bit-field is declared here}} + unsigned bitX : 4; // expected-note 3 {{bit-field is declared here}} unsigned bitY : 4; // expected-note {{bit-field is declared here}} unsigned var; @@ -50,7 +50,7 @@ namespace test3 { void test(A *a) { unsigned &t0 = a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}} - unsigned &t1 = (unsigned&) a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}} + unsigned &t1 = (unsigned&) a->bitX; // expected-error {{C-style cast from bit-field lvalue to reference type 'unsigned int &'}} unsigned &t2 = const_cast<unsigned&>(a->bitX); // expected-error {{const_cast from bit-field lvalue to reference type 'unsigned int &'}} unsigned &t3 = (a->foo(), a->bitX); // expected-error {{non-const reference cannot bind to bit-field 'bitX'}} unsigned &t4 = (a->var ? a->bitX : a->bitY); // expected-error {{non-const reference cannot bind to bit-field}} diff --git a/clang/test/CXX/drs/dr12xx.cpp b/clang/test/CXX/drs/dr12xx.cpp index c4f980a87dd..72d8d683ab7 100644 --- a/clang/test/CXX/drs/dr12xx.cpp +++ b/clang/test/CXX/drs/dr12xx.cpp @@ -3,8 +3,6 @@ // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -// expected-no-diagnostics - namespace dr1213 { // dr1213: 4.0 #if __cplusplus >= 201103L using T = int[3]; @@ -27,3 +25,29 @@ struct Derived : Base { virtual Incomplete *meow(); }; } // dr1250 + +namespace dr1295 { // dr1295: 4.0 + struct X { + unsigned bitfield : 4; + }; + + X x = {1}; + + unsigned const &r1 = static_cast<X &&>(x).bitfield; // expected-error 0-1{{C++11}} + unsigned const &r2 = static_cast<unsigned &&>(x.bitfield); // expected-error 0-1{{C++11}} + + template<unsigned &r> struct Y {}; + Y<x.bitfield> y; +#if __cplusplus <= 201402L + // expected-error@-2 {{does not refer to any declaration}} expected-note@-3 {{here}} +#else + // expected-error@-4 {{refers to subobject}} +#endif + +#if __cplusplus >= 201103L + const unsigned other = 0; + using T = decltype(true ? other : x.bitfield); + using T = unsigned; +#endif +} + diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 8ecf4a48481..a441405939e 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -386,6 +386,18 @@ namespace FakeInitList { constexpr init_list_2_init_list_3_ints ils = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } }; } +namespace ConstAddedByReference { + const int &r = (0); + constexpr int n = r; + + struct A { constexpr operator int() const { return 0; }}; + struct B { constexpr operator const int() const { return 0; }}; + const int &ra = A(); + const int &rb = B(); + constexpr int na = ra; + constexpr int nb = rb; +} + } constexpr int strcmp_ce(const char *p, const char *q) { diff --git a/clang/test/SemaCXX/constant-expression-cxx1z.cpp b/clang/test/SemaCXX/constant-expression-cxx1z.cpp index a045234ff9e..1563586e196 100644 --- a/clang/test/SemaCXX/constant-expression-cxx1z.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx1z.cpp @@ -39,3 +39,8 @@ namespace NoexceptFunctionTypes { static_assert(A<int>().g()); static_assert(A<int>()()); } + +namespace Cxx17CD_NB_GB19 { + const int &r = 0; + constexpr int n = r; +} diff --git a/clang/test/SemaCXX/member-init.cpp b/clang/test/SemaCXX/member-init.cpp index 836c1f7455e..20e4cec5bfd 100644 --- a/clang/test/SemaCXX/member-init.cpp +++ b/clang/test/SemaCXX/member-init.cpp @@ -87,7 +87,7 @@ namespace PR14838 { struct thing {}; struct another { another() : r(thing()) {} - // expected-error@-1 {{temporary of type 'const PR14838::function' has private destructor}} + // expected-error@-1 {{temporary of type 'PR14838::function' has private destructor}} // expected-warning@-2 {{binding reference member 'r' to a temporary value}} const function &r; // expected-note {{reference member declared here}} } af; diff --git a/clang/test/SemaCXX/microsoft-new-delete.cpp b/clang/test/SemaCXX/microsoft-new-delete.cpp index b929e618a03..beba4d9dd8a 100644 --- a/clang/test/SemaCXX/microsoft-new-delete.cpp +++ b/clang/test/SemaCXX/microsoft-new-delete.cpp @@ -16,7 +16,7 @@ void *operator new(size_t, const noncopyable&); void *q = new (nc) int[4]; // expected-error {{calling a private constructor}} struct bitfield { int n : 3; } bf; // expected-note {{here}} -void *operator new[](size_t, int &); +void *operator new[](size_t, int &); // expected-note {{passing argument to parameter here}} void *operator new(size_t, const int &); void *r = new (bf.n) int[4]; // expected-error {{non-const reference cannot bind to bit-field}} diff --git a/clang/test/SemaCXX/reinterpret-cast.cpp b/clang/test/SemaCXX/reinterpret-cast.cpp index 7c88dc0302a..6cc46d8b0d9 100644 --- a/clang/test/SemaCXX/reinterpret-cast.cpp +++ b/clang/test/SemaCXX/reinterpret-cast.cpp @@ -125,7 +125,7 @@ void const_arrays() { namespace PR9564 { struct a { int a : 10; }; a x; - int *y = &reinterpret_cast<int&>(x.a); // expected-error {{not allowed}} + int *y = &reinterpret_cast<int&>(x.a); // expected-error {{reinterpret_cast from bit-field lvalue to reference type 'int &'}} __attribute((ext_vector_type(4))) typedef float v4; float& w(v4 &a) { return reinterpret_cast<float&>(a[1]); } // expected-error {{not allowed}} |

