aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaNamedCast.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2009-01-27 23:18:31 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2009-01-27 23:18:31 +0000
commitdb64728e69a45b89870ede13944a934d3c2ed12a (patch)
treeeca37d78e6d8ddc21d7e36dc2011ed0756fe2132 /lib/Sema/SemaNamedCast.cpp
parent07236ba8d3cf1d2aa8cd173c440f3e7dc1249fd0 (diff)
Add handling of member pointers to reinterpret_cast.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63150 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaNamedCast.cpp')
-rw-r--r--lib/Sema/SemaNamedCast.cpp55
1 files changed, 40 insertions, 15 deletions
diff --git a/lib/Sema/SemaNamedCast.cpp b/lib/Sema/SemaNamedCast.cpp
index 17de7321de..e88a3b2079 100644
--- a/lib/Sema/SemaNamedCast.cpp
+++ b/lib/Sema/SemaNamedCast.cpp
@@ -237,6 +237,32 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
// Canonicalize source for comparison.
SrcType = Self.Context.getCanonicalType(SrcType);
+ const MemberPointerType *DestMemPtr = DestType->getAsMemberPointerType(),
+ *SrcMemPtr = SrcType->getAsMemberPointerType();
+ if (DestMemPtr && SrcMemPtr) {
+ // C++ 5.2.10p9: An rvalue of type "pointer to member of X of type T1"
+ // can be explicitly converted to an rvalue of type "pointer to member
+ // of Y of type T2" if T1 and T2 are both function types or both object
+ // types.
+ if (DestMemPtr->getPointeeType()->isFunctionType() !=
+ SrcMemPtr->getPointeeType()->isFunctionType()) {
+ Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic)
+ << "reinterpret_cast" << OrigDestType << OrigSrcType << OpRange;
+ return;
+ }
+
+ // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away
+ // constness.
+ if (CastsAwayConstness(Self, SrcType, DestType)) {
+ Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_const_away)
+ << "reinterpret_cast" << OrigDestType << OrigSrcType << OpRange;
+ return;
+ }
+
+ // A valid member pointer cast.
+ return;
+ }
+
bool destIsPtr = DestType->isPointerType();
bool srcIsPtr = SrcType->isPointerType();
if (!destIsPtr && !srcIsPtr) {
@@ -253,8 +279,8 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
// restrictions, a cast to the same type is allowed. The intent is not
// entirely clear here, since all other paragraphs explicitly forbid casts
// to the same type. However, the behavior of compilers is pretty consistent
- // on this point: allow same-type conversion if the involved are pointers,
- // disallow otherwise.
+ // on this point: allow same-type conversion if the involved types are
+ // pointers, disallow otherwise.
return;
}
@@ -304,8 +330,6 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
return;
}
- // FIXME: Handle member pointers.
-
// C++0x 5.2.10p8: Converting a pointer to a function into a pointer to
// an object type or vice versa is conditionally-supported.
// Compilers support it in C++03 too, though, because it's necessary for
@@ -319,8 +343,6 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
return;
}
- // FIXME: Handle member pointers.
-
if (DestType->isFunctionPointerType()) {
// See above.
if (!Self.getLangOptions().CPlusPlus0x) {
@@ -337,18 +359,21 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
// object pointers.
}
-/// CastsAwayConstness - Check if the pointer conversion from SrcType
-/// to DestType casts away constness as defined in C++
-/// 5.2.11p8ff. This is used by the cast checkers. Both arguments
-/// must denote pointer types.
+/// CastsAwayConstness - Check if the pointer conversion from SrcType to
+/// DestType casts away constness as defined in C++ 5.2.11p8ff. This is used by
+/// the cast checkers. Both arguments must denote pointer (possibly to member)
+/// types.
bool
CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType)
{
- // Casting away constness is defined in C++ 5.2.11p8 with reference to
- // C++ 4.4.
- // We piggyback on Sema::IsQualificationConversion for this, since the rules
- // are non-trivial. So first we construct Tcv *...cv* as described in
- // C++ 5.2.11p8.
+ // Casting away constness is defined in C++ 5.2.11p8 with reference to
+ // C++ 4.4. We piggyback on Sema::IsQualificationConversion for this, since
+ // the rules are non-trivial. So first we construct Tcv *...cv* as described
+ // in C++ 5.2.11p8.
+ assert((SrcType->isPointerType() || SrcType->isMemberPointerType()) &&
+ "Source type is not pointer or pointer to member.");
+ assert((DestType->isPointerType() || DestType->isMemberPointerType()) &&
+ "Destination type is not pointer or pointer to member.");
QualType UnwrappedSrcType = SrcType, UnwrappedDestType = DestType;
llvm::SmallVector<unsigned, 8> cv1, cv2;