summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-07-10 23:04:35 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-07-10 23:04:35 +0000
commitf276e2dc461833d3ef0b89a0b09d2e11776d9e84 (patch)
tree02b9a8f6fc1e84d6e2f6b4b71ed5689fbdd92d88 /clang/test
parent0ed0febb3e58081edf1c69b62d28f72703a417f8 (diff)
downloadbcm5719-llvm-f276e2dc461833d3ef0b89a0b09d2e11776d9e84.tar.gz
bcm5719-llvm-f276e2dc461833d3ef0b89a0b09d2e11776d9e84.zip
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. llvm-svn: 336738
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/expr/expr.post/expr.reinterpret.cast/p2.cpp26
-rw-r--r--clang/test/Sema/warn-cast-qual.c10
2 files changed, 33 insertions, 3 deletions
diff --git a/clang/test/CXX/expr/expr.post/expr.reinterpret.cast/p2.cpp b/clang/test/CXX/expr/expr.post/expr.reinterpret.cast/p2.cpp
new file mode 100644
index 00000000000..b03db27ee1d
--- /dev/null
+++ b/clang/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
+}
diff --git a/clang/test/Sema/warn-cast-qual.c b/clang/test/Sema/warn-cast-qual.c
index a682cad75ed..789bde15b13 100644
--- a/clang/test/Sema/warn-cast-qual.c
+++ b/clang/test/Sema/warn-cast-qual.c
@@ -4,11 +4,15 @@
#include <stdint.h>
void foo() {
- const char * const ptr = 0;
- const char * const *ptrptr = 0;
+ const char *const ptr = 0;
+ const char *const *ptrptr = 0;
+ char *const *ptrcptr = 0;
+ char **ptrptr2 = 0;
char *y = (char *)ptr; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}}
- char **y1 = (char **)ptrptr; // expected-warning {{cast from 'const char *const' to 'char *' drops const qualifier}}
+ char **y1 = (char **)ptrptr; // expected-warning {{cast from 'const char *const *' to 'char **' drops const qualifier}}
const char **y2 = (const char **)ptrptr; // expected-warning {{cast from 'const char *const *' to 'const char **' drops const qualifier}}
+ char *const *y3 = (char *const *)ptrptr; // expected-warning {{cast from 'const char *const' to 'char *const' drops const qualifier}}
+ const char **y4 = (const char **)ptrcptr; // expected-warning {{cast from 'char *const *' to 'const char **' drops const qualifier}}
char *z = (char *)(uintptr_t)(const void *)ptr; // no warning
char *z1 = (char *)(const void *)ptr; // expected-warning {{cast from 'const void *' to 'char *' drops const qualifier}}
OpenPOWER on IntegriCloud