diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-10 23:04:35 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-10 23:04:35 +0000 |
commit | 284abf4f1cb32a5f7a3134209c5d7b83923c720d (patch) | |
tree | d5ee7bb6ec54a1811cb0006b2e1b45eef1dc4922 /test/CXX | |
parent | 032aa95be6020f58220afb96afceaa25829236c9 (diff) |
Fix determination of whether a reinterpret_cast casts away constness.
The "casts away constness" check doesn't care at all how the different
layers of the source and destination type were formed: for example, if
the source is a pointer and the destination is a pointer-to-member, the
types are still decomposed and their pointee qualifications are still
checked.
This rule is bizarre and somewhat ridiculous, so as an extension we
accept code making use of such reinterpret_casts with a warning outside
of SFINAE contexts.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@336738 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CXX')
-rw-r--r-- | test/CXX/expr/expr.post/expr.reinterpret.cast/p2.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/test/CXX/expr/expr.post/expr.reinterpret.cast/p2.cpp b/test/CXX/expr/expr.post/expr.reinterpret.cast/p2.cpp new file mode 100644 index 0000000000..b03db27ee1 --- /dev/null +++ b/test/CXX/expr/expr.post/expr.reinterpret.cast/p2.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 %s -verify + +// The reinterpret_cast operator shall not cast away constness. +struct X {}; +struct Y {}; +void f(const int * X::* Y::* *p) { + // This applies for similar types... + (void)reinterpret_cast<int * X::* Y::* *>(p); // expected-error {{casts away qualifiers}} + // ... and for cases where the base type is different ... + (void)reinterpret_cast<float * X::* Y::* *>(p); // expected-error {{casts away qualifiers}} + // ... and for cases where pointers to members point to members of different classes ... + (void)reinterpret_cast<int * Y::* X::* *>(p); // expected-error {{casts away qualifiers}} + // ... and even for cases where the path is wholly different! + // (Though we accept such cases as an extension.) + (void)reinterpret_cast<double Y::* X::* * *>(p); // expected-warning {{casts away qualifiers}} + + // If qualifiers are added, we need a 'const' at every level above. + (void)reinterpret_cast<const volatile double Y::* X::* * *>(p); // expected-warning {{casts away qualifiers}} + (void)reinterpret_cast<const volatile double Y::*const X::*const **>(p); // expected-warning {{casts away qualifiers}} + (void)reinterpret_cast<const volatile double Y::*const X::**const *>(p); // expected-warning {{casts away qualifiers}} + (void)reinterpret_cast<const volatile double Y::*X::*const *const *>(p); // expected-warning {{casts away qualifiers}} + (void)reinterpret_cast<const volatile double Y::*const X::*const *const *>(p); // ok + + (void)reinterpret_cast<const double Y::*volatile X::**const *>(p); // expected-warning {{casts away qualifiers}} + (void)reinterpret_cast<const double Y::*volatile X::*const *const *>(p); // ok +} |