From b78fecaf6fc62796a9aea97fd601705bfe946bc7 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 24 Apr 2010 19:22:20 +0000 Subject: [PATCH] Add base paths to CK_UncheckedDerivedToBase and CK_DerivedToBaseMemberPointer. llvm-svn: 102260 --- clang/include/clang/AST/Expr.h | 4 ++-- clang/lib/Sema/Sema.cpp | 3 +-- clang/lib/Sema/SemaCXXCast.cpp | 20 ++++++++++++-------- clang/lib/Sema/SemaExpr.cpp | 19 ++++++++++--------- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 10e9a289cce0..60cb2f0039f6 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1659,14 +1659,14 @@ private: #ifndef NDEBUG switch (getCastKind()) { case CK_DerivedToBase: + case CK_UncheckedDerivedToBase: + case CK_DerivedToBaseMemberPointer: assert(!BasePath.empty() && "Cast kind should have a base path!"); break; // FIXME: We should add inheritance paths for these. case CK_BaseToDerived: - case CK_UncheckedDerivedToBase: case CK_BaseToDerivedMemberPointer: - case CK_DerivedToBaseMemberPointer: // These should not have an inheritance path. case CK_Unknown: diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 6975da0b3e34..755af84ca960 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -178,8 +178,7 @@ void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty, CheckImplicitConversion(Expr, Ty); if (ImplicitCastExpr *ImpCast = dyn_cast(Expr)) { - if (ImpCast->getCastKind() == Kind) { - assert(BasePath.empty() && "FIXME: Merge paths!"); + if (ImpCast->getCastKind() == Kind && BasePath.empty()) { ImpCast->setType(Ty); ImpCast->setLvalueCast(isLvalue); return; diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp index a62effa4a713..c827070fac94 100644 --- a/clang/lib/Sema/SemaCXXCast.cpp +++ b/clang/lib/Sema/SemaCXXCast.cpp @@ -86,11 +86,13 @@ static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, QualType OrigDestType, unsigned &msg, CastExpr::CastKind &Kind); static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, - QualType SrcType, - QualType DestType,bool CStyle, - const SourceRange &OpRange, - unsigned &msg, - CastExpr::CastKind &Kind); + QualType SrcType, + QualType DestType,bool CStyle, + const SourceRange &OpRange, + unsigned &msg, + CastExpr::CastKind &Kind, + CXXBaseSpecifierArray &BasePath); + static TryCastResult TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType, bool CStyle, const SourceRange &OpRange, @@ -550,7 +552,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr, // conversion. C++ 5.2.9p9 has additional information. // DR54's access restrictions apply here also. tcr = TryStaticMemberPointerUpcast(Self, SrcExpr, SrcType, DestType, CStyle, - OpRange, msg, Kind); + OpRange, msg, Kind, BasePath); if (tcr != TC_NotApplicable) return tcr; @@ -796,7 +798,8 @@ TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType, QualType DestType, bool CStyle, const SourceRange &OpRange, - unsigned &msg, CastExpr::CastKind &Kind) { + unsigned &msg, CastExpr::CastKind &Kind, + CXXBaseSpecifierArray &BasePath) { const MemberPointerType *DestMemPtr = DestType->getAs(); if (!DestMemPtr) return TC_NotApplicable; @@ -828,7 +831,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType, // B base of D QualType SrcClass(SrcMemPtr->getClass(), 0); QualType DestClass(DestMemPtr->getClass(), 0); - CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/!CStyle, + CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/true); if (!Self.IsDerivedFrom(SrcClass, DestClass, Paths)) { return TC_NotApplicable; @@ -882,6 +885,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType, } } + Self.BuildBasePathArray(Paths, BasePath); Kind = CastExpr::CK_DerivedToBaseMemberPointer; return TC_Success; } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c576bcd3aaa2..12223546b6f2 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1436,14 +1436,15 @@ Sema::PerformObjectMemberConversion(Expr *&From, // type of the object type, in which case we just ignore it. // Otherwise build the appropriate casts. if (IsDerivedFrom(FromRecordType, QRecordType)) { + CXXBaseSpecifierArray BasePath; if (CheckDerivedToBaseConversion(FromRecordType, QRecordType, - FromLoc, FromRange)) + FromLoc, FromRange, &BasePath)) return true; if (PointerConversions) QType = Context.getPointerType(QType); ImpCastExprToType(From, QType, CastExpr::CK_UncheckedDerivedToBase, - /*isLvalue=*/!PointerConversions); + /*isLvalue=*/!PointerConversions, BasePath); FromType = QType; FromRecordType = QRecordType; @@ -1471,15 +1472,16 @@ Sema::PerformObjectMemberConversion(Expr *&From, // conversion is non-trivial. if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) { assert(IsDerivedFrom(FromRecordType, URecordType)); + CXXBaseSpecifierArray BasePath; if (CheckDerivedToBaseConversion(FromRecordType, URecordType, - FromLoc, FromRange)) + FromLoc, FromRange, &BasePath)) return true; QualType UType = URecordType; if (PointerConversions) UType = Context.getPointerType(UType); ImpCastExprToType(From, UType, CastExpr::CK_UncheckedDerivedToBase, - /*isLvalue*/ !PointerConversions); + /*isLvalue=*/!PointerConversions, BasePath); FromType = UType; FromRecordType = URecordType; } @@ -1489,15 +1491,14 @@ Sema::PerformObjectMemberConversion(Expr *&From, IgnoreAccess = true; } - if (CheckDerivedToBaseConversion(FromRecordType, - DestRecordType, - FromLoc, - FromRange, 0, + CXXBaseSpecifierArray BasePath; + if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType, + FromLoc, FromRange, &BasePath, IgnoreAccess)) return true; ImpCastExprToType(From, DestType, CastExpr::CK_UncheckedDerivedToBase, - /*isLvalue=*/!PointerConversions); + /*isLvalue=*/!PointerConversions, BasePath); return false; }