diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-11 00:19:19 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-11 00:19:19 +0000 |
commit | 295c88685f7c285358db0d83f1fc315ac23677e3 (patch) | |
tree | 054f8c88ea571d0fddb19dcb52bc312451994ba2 /test | |
parent | 3c6b78637e54fd4bc2f6413e2f34439b51da65fa (diff) | |
download | clang-295c88685f7c285358db0d83f1fc315ac23677e3.tar.gz |
DR330: look through array types when forming the cv-decomposition of a type.
This allows more qualification conversions, eg. conversion from
'int *(*)[]' -> 'const int *const (*)[]'
is now permitted, along with all the consequences of that: more types
are similar, more cases are permitted by const_cast, and conversely,
fewer "casting away constness" cases are permitted by reinterpret_cast.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@336745 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/CXX/drs/dr3xx.cpp | 51 | ||||
-rw-r--r-- | test/SemaCXX/const-cast.cpp | 10 |
2 files changed, 59 insertions, 2 deletions
diff --git a/test/CXX/drs/dr3xx.cpp b/test/CXX/drs/dr3xx.cpp index 15261007dd..04fd258a7c 100644 --- a/test/CXX/drs/dr3xx.cpp +++ b/test/CXX/drs/dr3xx.cpp @@ -354,6 +354,57 @@ namespace dr329 { // dr329: 3.5 } } +namespace dr330 { // dr330: 7 + // Conversions between P and Q will be allowed by P0388. + typedef int *(*P)[3]; + typedef const int *const (*Q)[3]; + typedef const int *Qinner[3]; + typedef Qinner const *Q2; // same as Q, but 'const' written outside the array type + typedef const int *const (*R)[4]; + typedef const int *const (*S)[]; + typedef const int *(*T)[]; + void f(P p, Q q, Q2 q2, R r, S s, T t) { + q = p; // ok + q2 = p; // ok + r = p; // expected-error {{incompatible}} + s = p; // expected-error {{incompatible}} (for now) + t = p; // expected-error {{incompatible}} + s = q; // expected-error {{incompatible}} + s = q2; // expected-error {{incompatible}} + s = t; // ok, adding const + t = s; // expected-error {{incompatible}} + (void) const_cast<P>(q); + (void) const_cast<P>(q2); + (void) const_cast<Q>(p); + (void) const_cast<Q2>(p); + (void) const_cast<S>(p); // expected-error {{not allowed}} (for now) + (void) const_cast<P>(s); // expected-error {{not allowed}} (for now) + (void) const_cast<S>(q); // expected-error {{not allowed}} + (void) const_cast<S>(q2); // expected-error {{not allowed}} + (void) const_cast<Q>(s); // expected-error {{not allowed}} + (void) const_cast<Q2>(s); // expected-error {{not allowed}} + (void) const_cast<T>(s); + (void) const_cast<S>(t); + (void) const_cast<T>(q); // expected-error {{not allowed}} + (void) const_cast<Q>(t); // expected-error {{not allowed}} + + (void) reinterpret_cast<P>(q); // expected-error {{casts away qualifiers}} + (void) reinterpret_cast<P>(q2); // expected-error {{casts away qualifiers}} + (void) reinterpret_cast<Q>(p); + (void) reinterpret_cast<Q2>(p); + (void) reinterpret_cast<S>(p); + (void) reinterpret_cast<P>(s); // expected-error {{casts away qualifiers}} + (void) reinterpret_cast<S>(q); + (void) reinterpret_cast<S>(q2); + (void) reinterpret_cast<Q>(s); + (void) reinterpret_cast<Q2>(s); + (void) reinterpret_cast<T>(s); // expected-error {{casts away qualifiers}} + (void) reinterpret_cast<S>(t); + (void) reinterpret_cast<T>(q); // expected-error {{casts away qualifiers}} + (void) reinterpret_cast<Q>(t); + } +} + namespace dr331 { // dr331: yes struct A { A(volatile A&); // expected-note {{candidate}} diff --git a/test/SemaCXX/const-cast.cpp b/test/SemaCXX/const-cast.cpp index 87df61cbc7..a9268660f1 100644 --- a/test/SemaCXX/const-cast.cpp +++ b/test/SemaCXX/const-cast.cpp @@ -58,8 +58,14 @@ short *bad_const_cast_test(char const *volatile *const volatile *var) // Non-pointer. char v = const_cast<char>(**var2); // expected-error {{const_cast to 'char', which is not a reference, pointer-to-object, or pointer-to-data-member}} const int *ar[100] = {0}; - // Not even lenient g++ accepts this. - int *(*rar)[100] = const_cast<int *(*)[100]>(&ar); // expected-error {{const_cast from 'const int *(*)[100]' to 'int *(*)[100]' is not allowed}} + extern const int *aub[]; + // const_cast looks through arrays as of DR330. + (void) const_cast<int *(*)[100]>(&ar); // ok + (void) const_cast<int *(*)[]>(&aub); // ok + // ... but the array bound must exactly match. + (void) const_cast<int *(*)[]>(&ar); // expected-error {{const_cast from 'const int *(*)[100]' to 'int *(*)[]' is not allowed}} + (void) const_cast<int *(*)[99]>(&ar); // expected-error {{const_cast from 'const int *(*)[100]' to 'int *(*)[99]' is not allowed}} + (void) const_cast<int *(*)[100]>(&aub); // expected-error {{const_cast from 'const int *(*)[]' to 'int *(*)[100]' is not allowed}} f fp1 = 0; // Function pointers. f fp2 = const_cast<f>(fp1); // expected-error {{const_cast to 'f' (aka 'int (*)(int)'), which is not a reference, pointer-to-object, or pointer-to-data-member}} |