1226586Sdim//===--- SemaCast.cpp - Semantic Analysis for Casts -----------------------===// 2226586Sdim// 3226586Sdim// The LLVM Compiler Infrastructure 4226586Sdim// 5226586Sdim// This file is distributed under the University of Illinois Open Source 6226586Sdim// License. See LICENSE.TXT for details. 7226586Sdim// 8226586Sdim//===----------------------------------------------------------------------===// 9226586Sdim// 10226586Sdim// This file implements semantic analysis for cast expressions, including 11226586Sdim// 1) C-style casts like '(int) x' 12226586Sdim// 2) C++ functional casts like 'int(x)' 13226586Sdim// 3) C++ named casts like 'static_cast<int>(x)' 14226586Sdim// 15226586Sdim//===----------------------------------------------------------------------===// 16226586Sdim 17226586Sdim#include "clang/Sema/SemaInternal.h" 18249423Sdim#include "clang/AST/ASTContext.h" 19249423Sdim#include "clang/AST/CXXInheritance.h" 20226586Sdim#include "clang/AST/ExprCXX.h" 21226586Sdim#include "clang/AST/ExprObjC.h" 22249423Sdim#include "clang/AST/RecordLayout.h" 23226586Sdim#include "clang/Basic/PartialDiagnostic.h" 24249423Sdim#include "clang/Sema/Initialization.h" 25226586Sdim#include "llvm/ADT/SmallVector.h" 26226586Sdim#include <set> 27226586Sdimusing namespace clang; 28226586Sdim 29226586Sdim 30226586Sdim 31226586Sdimenum TryCastResult { 32226586Sdim TC_NotApplicable, ///< The cast method is not applicable. 33226586Sdim TC_Success, ///< The cast method is appropriate and successful. 34226586Sdim TC_Failed ///< The cast method is appropriate, but failed. A 35226586Sdim ///< diagnostic has been emitted. 36226586Sdim}; 37226586Sdim 38226586Sdimenum CastType { 39226586Sdim CT_Const, ///< const_cast 40226586Sdim CT_Static, ///< static_cast 41226586Sdim CT_Reinterpret, ///< reinterpret_cast 42226586Sdim CT_Dynamic, ///< dynamic_cast 43226586Sdim CT_CStyle, ///< (Type)expr 44226586Sdim CT_Functional ///< Type(expr) 45226586Sdim}; 46226586Sdim 47226586Sdimnamespace { 48226586Sdim struct CastOperation { 49226586Sdim CastOperation(Sema &S, QualType destType, ExprResult src) 50226586Sdim : Self(S), SrcExpr(src), DestType(destType), 51226586Sdim ResultType(destType.getNonLValueExprType(S.Context)), 52226586Sdim ValueKind(Expr::getValueKindForType(destType)), 53234353Sdim Kind(CK_Dependent), IsARCUnbridgedCast(false) { 54226586Sdim 55226586Sdim if (const BuiltinType *placeholder = 56226586Sdim src.get()->getType()->getAsPlaceholderType()) { 57226586Sdim PlaceholderKind = placeholder->getKind(); 58226586Sdim } else { 59226586Sdim PlaceholderKind = (BuiltinType::Kind) 0; 60226586Sdim } 61226586Sdim } 62226586Sdim 63226586Sdim Sema &Self; 64226586Sdim ExprResult SrcExpr; 65226586Sdim QualType DestType; 66226586Sdim QualType ResultType; 67226586Sdim ExprValueKind ValueKind; 68226586Sdim CastKind Kind; 69226586Sdim BuiltinType::Kind PlaceholderKind; 70226586Sdim CXXCastPath BasePath; 71234353Sdim bool IsARCUnbridgedCast; 72226586Sdim 73226586Sdim SourceRange OpRange; 74226586Sdim SourceRange DestRange; 75226586Sdim 76226586Sdim // Top-level semantics-checking routines. 77226586Sdim void CheckConstCast(); 78226586Sdim void CheckReinterpretCast(); 79226586Sdim void CheckStaticCast(); 80226586Sdim void CheckDynamicCast(); 81234353Sdim void CheckCXXCStyleCast(bool FunctionalCast, bool ListInitialization); 82226586Sdim void CheckCStyleCast(); 83226586Sdim 84234353Sdim /// Complete an apparently-successful cast operation that yields 85234353Sdim /// the given expression. 86234353Sdim ExprResult complete(CastExpr *castExpr) { 87234353Sdim // If this is an unbridged cast, wrap the result in an implicit 88234353Sdim // cast that yields the unbridged-cast placeholder type. 89234353Sdim if (IsARCUnbridgedCast) { 90234353Sdim castExpr = ImplicitCastExpr::Create(Self.Context, 91234353Sdim Self.Context.ARCUnbridgedCastTy, 92234353Sdim CK_Dependent, castExpr, 0, 93234353Sdim castExpr->getValueKind()); 94234353Sdim } 95234353Sdim return Self.Owned(castExpr); 96234353Sdim } 97234353Sdim 98226586Sdim // Internal convenience methods. 99226586Sdim 100226586Sdim /// Try to handle the given placeholder expression kind. Return 101226586Sdim /// true if the source expression has the appropriate placeholder 102226586Sdim /// kind. A placeholder can only be claimed once. 103226586Sdim bool claimPlaceholder(BuiltinType::Kind K) { 104226586Sdim if (PlaceholderKind != K) return false; 105226586Sdim 106226586Sdim PlaceholderKind = (BuiltinType::Kind) 0; 107226586Sdim return true; 108226586Sdim } 109226586Sdim 110226586Sdim bool isPlaceholder() const { 111226586Sdim return PlaceholderKind != 0; 112226586Sdim } 113226586Sdim bool isPlaceholder(BuiltinType::Kind K) const { 114226586Sdim return PlaceholderKind == K; 115226586Sdim } 116226586Sdim 117226586Sdim void checkCastAlign() { 118226586Sdim Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange); 119226586Sdim } 120226586Sdim 121226586Sdim void checkObjCARCConversion(Sema::CheckedConversionKind CCK) { 122234353Sdim assert(Self.getLangOpts().ObjCAutoRefCount); 123234353Sdim 124226586Sdim Expr *src = SrcExpr.get(); 125234353Sdim if (Self.CheckObjCARCConversion(OpRange, DestType, src, CCK) == 126234353Sdim Sema::ACR_unbridged) 127234353Sdim IsARCUnbridgedCast = true; 128226586Sdim SrcExpr = src; 129226586Sdim } 130226586Sdim 131226586Sdim /// Check for and handle non-overload placeholder expressions. 132226586Sdim void checkNonOverloadPlaceholders() { 133226586Sdim if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload)) 134226586Sdim return; 135226586Sdim 136226586Sdim SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take()); 137226586Sdim if (SrcExpr.isInvalid()) 138226586Sdim return; 139226586Sdim PlaceholderKind = (BuiltinType::Kind) 0; 140226586Sdim } 141226586Sdim }; 142226586Sdim} 143226586Sdim 144226586Sdimstatic bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, 145226586Sdim bool CheckCVR, bool CheckObjCLifetime); 146226586Sdim 147226586Sdim// The Try functions attempt a specific way of casting. If they succeed, they 148226586Sdim// return TC_Success. If their way of casting is not appropriate for the given 149226586Sdim// arguments, they return TC_NotApplicable and *may* set diag to a diagnostic 150226586Sdim// to emit if no other way succeeds. If their way of casting is appropriate but 151226586Sdim// fails, they return TC_Failed and *must* set diag; they can set it to 0 if 152226586Sdim// they emit a specialized diagnostic. 153226586Sdim// All diagnostics returned by these functions must expect the same three 154226586Sdim// arguments: 155226586Sdim// %0: Cast Type (a value from the CastType enumeration) 156226586Sdim// %1: Source Type 157226586Sdim// %2: Destination Type 158226586Sdimstatic TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, 159226586Sdim QualType DestType, bool CStyle, 160226586Sdim CastKind &Kind, 161226586Sdim CXXCastPath &BasePath, 162226586Sdim unsigned &msg); 163226586Sdimstatic TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, 164226586Sdim QualType DestType, bool CStyle, 165226586Sdim const SourceRange &OpRange, 166226586Sdim unsigned &msg, 167226586Sdim CastKind &Kind, 168226586Sdim CXXCastPath &BasePath); 169226586Sdimstatic TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType, 170226586Sdim QualType DestType, bool CStyle, 171226586Sdim const SourceRange &OpRange, 172226586Sdim unsigned &msg, 173226586Sdim CastKind &Kind, 174226586Sdim CXXCastPath &BasePath); 175226586Sdimstatic TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, 176226586Sdim CanQualType DestType, bool CStyle, 177226586Sdim const SourceRange &OpRange, 178226586Sdim QualType OrigSrcType, 179226586Sdim QualType OrigDestType, unsigned &msg, 180226586Sdim CastKind &Kind, 181226586Sdim CXXCastPath &BasePath); 182226586Sdimstatic TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, 183226586Sdim QualType SrcType, 184226586Sdim QualType DestType,bool CStyle, 185226586Sdim const SourceRange &OpRange, 186226586Sdim unsigned &msg, 187226586Sdim CastKind &Kind, 188226586Sdim CXXCastPath &BasePath); 189226586Sdim 190226586Sdimstatic TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, 191226586Sdim QualType DestType, 192226586Sdim Sema::CheckedConversionKind CCK, 193226586Sdim const SourceRange &OpRange, 194234353Sdim unsigned &msg, CastKind &Kind, 195234353Sdim bool ListInitialization); 196226586Sdimstatic TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, 197226586Sdim QualType DestType, 198226586Sdim Sema::CheckedConversionKind CCK, 199226586Sdim const SourceRange &OpRange, 200234353Sdim unsigned &msg, CastKind &Kind, 201234353Sdim CXXCastPath &BasePath, 202234353Sdim bool ListInitialization); 203263508Sdimstatic TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr, 204263508Sdim QualType DestType, bool CStyle, 205263508Sdim unsigned &msg); 206226586Sdimstatic TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, 207226586Sdim QualType DestType, bool CStyle, 208226586Sdim const SourceRange &OpRange, 209226586Sdim unsigned &msg, 210226586Sdim CastKind &Kind); 211226586Sdim 212226586Sdim 213226586Sdim/// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's. 214226586SdimExprResult 215226586SdimSema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, 216226586Sdim SourceLocation LAngleBracketLoc, Declarator &D, 217226586Sdim SourceLocation RAngleBracketLoc, 218226586Sdim SourceLocation LParenLoc, Expr *E, 219226586Sdim SourceLocation RParenLoc) { 220226586Sdim 221226586Sdim assert(!D.isInvalidType()); 222226586Sdim 223226586Sdim TypeSourceInfo *TInfo = GetTypeForDeclaratorCast(D, E->getType()); 224226586Sdim if (D.isInvalidType()) 225226586Sdim return ExprError(); 226226586Sdim 227234353Sdim if (getLangOpts().CPlusPlus) { 228226586Sdim // Check that there are no default arguments (C++ only). 229226586Sdim CheckExtraCXXDefaultArguments(D); 230226586Sdim } 231226586Sdim 232243830Sdim return BuildCXXNamedCast(OpLoc, Kind, TInfo, E, 233226586Sdim SourceRange(LAngleBracketLoc, RAngleBracketLoc), 234226586Sdim SourceRange(LParenLoc, RParenLoc)); 235226586Sdim} 236226586Sdim 237226586SdimExprResult 238226586SdimSema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, 239226586Sdim TypeSourceInfo *DestTInfo, Expr *E, 240226586Sdim SourceRange AngleBrackets, SourceRange Parens) { 241226586Sdim ExprResult Ex = Owned(E); 242226586Sdim QualType DestType = DestTInfo->getType(); 243226586Sdim 244226586Sdim // If the type is dependent, we won't do the semantic analysis now. 245226586Sdim // FIXME: should we check this in a more fine-grained manner? 246263508Sdim bool TypeDependent = DestType->isDependentType() || 247263508Sdim Ex.get()->isTypeDependent() || 248263508Sdim Ex.get()->isValueDependent(); 249226586Sdim 250226586Sdim CastOperation Op(*this, DestType, E); 251226586Sdim Op.OpRange = SourceRange(OpLoc, Parens.getEnd()); 252226586Sdim Op.DestRange = AngleBrackets; 253226586Sdim 254226586Sdim switch (Kind) { 255226586Sdim default: llvm_unreachable("Unknown C++ cast!"); 256226586Sdim 257226586Sdim case tok::kw_const_cast: 258226586Sdim if (!TypeDependent) { 259226586Sdim Op.CheckConstCast(); 260226586Sdim if (Op.SrcExpr.isInvalid()) 261226586Sdim return ExprError(); 262226586Sdim } 263234353Sdim return Op.complete(CXXConstCastExpr::Create(Context, Op.ResultType, 264234353Sdim Op.ValueKind, Op.SrcExpr.take(), DestTInfo, 265249423Sdim OpLoc, Parens.getEnd(), 266249423Sdim AngleBrackets)); 267226586Sdim 268226586Sdim case tok::kw_dynamic_cast: { 269226586Sdim if (!TypeDependent) { 270226586Sdim Op.CheckDynamicCast(); 271226586Sdim if (Op.SrcExpr.isInvalid()) 272226586Sdim return ExprError(); 273226586Sdim } 274234353Sdim return Op.complete(CXXDynamicCastExpr::Create(Context, Op.ResultType, 275234353Sdim Op.ValueKind, Op.Kind, Op.SrcExpr.take(), 276234353Sdim &Op.BasePath, DestTInfo, 277249423Sdim OpLoc, Parens.getEnd(), 278249423Sdim AngleBrackets)); 279226586Sdim } 280226586Sdim case tok::kw_reinterpret_cast: { 281226586Sdim if (!TypeDependent) { 282226586Sdim Op.CheckReinterpretCast(); 283226586Sdim if (Op.SrcExpr.isInvalid()) 284226586Sdim return ExprError(); 285226586Sdim } 286234353Sdim return Op.complete(CXXReinterpretCastExpr::Create(Context, Op.ResultType, 287234353Sdim Op.ValueKind, Op.Kind, Op.SrcExpr.take(), 288234353Sdim 0, DestTInfo, OpLoc, 289249423Sdim Parens.getEnd(), 290249423Sdim AngleBrackets)); 291226586Sdim } 292226586Sdim case tok::kw_static_cast: { 293226586Sdim if (!TypeDependent) { 294226586Sdim Op.CheckStaticCast(); 295226586Sdim if (Op.SrcExpr.isInvalid()) 296226586Sdim return ExprError(); 297226586Sdim } 298226586Sdim 299234353Sdim return Op.complete(CXXStaticCastExpr::Create(Context, Op.ResultType, 300234353Sdim Op.ValueKind, Op.Kind, Op.SrcExpr.take(), 301234353Sdim &Op.BasePath, DestTInfo, 302249423Sdim OpLoc, Parens.getEnd(), 303249423Sdim AngleBrackets)); 304226586Sdim } 305226586Sdim } 306226586Sdim} 307226586Sdim 308226586Sdim/// Try to diagnose a failed overloaded cast. Returns true if 309226586Sdim/// diagnostics were emitted. 310226586Sdimstatic bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, 311226586Sdim SourceRange range, Expr *src, 312234353Sdim QualType destType, 313234353Sdim bool listInitialization) { 314226586Sdim switch (CT) { 315226586Sdim // These cast kinds don't consider user-defined conversions. 316226586Sdim case CT_Const: 317226586Sdim case CT_Reinterpret: 318226586Sdim case CT_Dynamic: 319226586Sdim return false; 320226586Sdim 321226586Sdim // These do. 322226586Sdim case CT_Static: 323226586Sdim case CT_CStyle: 324226586Sdim case CT_Functional: 325226586Sdim break; 326226586Sdim } 327226586Sdim 328226586Sdim QualType srcType = src->getType(); 329226586Sdim if (!destType->isRecordType() && !srcType->isRecordType()) 330226586Sdim return false; 331226586Sdim 332226586Sdim InitializedEntity entity = InitializedEntity::InitializeTemporary(destType); 333226586Sdim InitializationKind initKind 334226586Sdim = (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(), 335234353Sdim range, listInitialization) 336234353Sdim : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range, 337234353Sdim listInitialization) 338226586Sdim : InitializationKind::CreateCast(/*type range?*/ range); 339251662Sdim InitializationSequence sequence(S, entity, initKind, src); 340226586Sdim 341226586Sdim assert(sequence.Failed() && "initialization succeeded on second try?"); 342226586Sdim switch (sequence.getFailureKind()) { 343226586Sdim default: return false; 344226586Sdim 345226586Sdim case InitializationSequence::FK_ConstructorOverloadFailed: 346226586Sdim case InitializationSequence::FK_UserConversionOverloadFailed: 347226586Sdim break; 348226586Sdim } 349226586Sdim 350226586Sdim OverloadCandidateSet &candidates = sequence.getFailedCandidateSet(); 351226586Sdim 352226586Sdim unsigned msg = 0; 353226586Sdim OverloadCandidateDisplayKind howManyCandidates = OCD_AllCandidates; 354226586Sdim 355226586Sdim switch (sequence.getFailedOverloadResult()) { 356226586Sdim case OR_Success: llvm_unreachable("successful failed overload"); 357226586Sdim case OR_No_Viable_Function: 358226586Sdim if (candidates.empty()) 359226586Sdim msg = diag::err_ovl_no_conversion_in_cast; 360226586Sdim else 361226586Sdim msg = diag::err_ovl_no_viable_conversion_in_cast; 362226586Sdim howManyCandidates = OCD_AllCandidates; 363226586Sdim break; 364226586Sdim 365226586Sdim case OR_Ambiguous: 366226586Sdim msg = diag::err_ovl_ambiguous_conversion_in_cast; 367226586Sdim howManyCandidates = OCD_ViableCandidates; 368226586Sdim break; 369226586Sdim 370226586Sdim case OR_Deleted: 371226586Sdim msg = diag::err_ovl_deleted_conversion_in_cast; 372226586Sdim howManyCandidates = OCD_ViableCandidates; 373226586Sdim break; 374226586Sdim } 375226586Sdim 376226586Sdim S.Diag(range.getBegin(), msg) 377226586Sdim << CT << srcType << destType 378226586Sdim << range << src->getSourceRange(); 379226586Sdim 380234353Sdim candidates.NoteCandidates(S, howManyCandidates, src); 381226586Sdim 382226586Sdim return true; 383226586Sdim} 384226586Sdim 385226586Sdim/// Diagnose a failed cast. 386226586Sdimstatic void diagnoseBadCast(Sema &S, unsigned msg, CastType castType, 387234353Sdim SourceRange opRange, Expr *src, QualType destType, 388234353Sdim bool listInitialization) { 389226586Sdim if (msg == diag::err_bad_cxx_cast_generic && 390234353Sdim tryDiagnoseOverloadedCast(S, castType, opRange, src, destType, 391234353Sdim listInitialization)) 392226586Sdim return; 393226586Sdim 394226586Sdim S.Diag(opRange.getBegin(), msg) << castType 395226586Sdim << src->getType() << destType << opRange << src->getSourceRange(); 396226586Sdim} 397226586Sdim 398226586Sdim/// UnwrapDissimilarPointerTypes - Like Sema::UnwrapSimilarPointerTypes, 399226586Sdim/// this removes one level of indirection from both types, provided that they're 400226586Sdim/// the same kind of pointer (plain or to-member). Unlike the Sema function, 401226586Sdim/// this one doesn't care if the two pointers-to-member don't point into the 402226586Sdim/// same class. This is because CastsAwayConstness doesn't care. 403226586Sdimstatic bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) { 404226586Sdim const PointerType *T1PtrType = T1->getAs<PointerType>(), 405226586Sdim *T2PtrType = T2->getAs<PointerType>(); 406226586Sdim if (T1PtrType && T2PtrType) { 407226586Sdim T1 = T1PtrType->getPointeeType(); 408226586Sdim T2 = T2PtrType->getPointeeType(); 409226586Sdim return true; 410226586Sdim } 411226586Sdim const ObjCObjectPointerType *T1ObjCPtrType = 412226586Sdim T1->getAs<ObjCObjectPointerType>(), 413226586Sdim *T2ObjCPtrType = 414226586Sdim T2->getAs<ObjCObjectPointerType>(); 415226586Sdim if (T1ObjCPtrType) { 416226586Sdim if (T2ObjCPtrType) { 417226586Sdim T1 = T1ObjCPtrType->getPointeeType(); 418226586Sdim T2 = T2ObjCPtrType->getPointeeType(); 419226586Sdim return true; 420226586Sdim } 421226586Sdim else if (T2PtrType) { 422226586Sdim T1 = T1ObjCPtrType->getPointeeType(); 423226586Sdim T2 = T2PtrType->getPointeeType(); 424226586Sdim return true; 425226586Sdim } 426226586Sdim } 427226586Sdim else if (T2ObjCPtrType) { 428226586Sdim if (T1PtrType) { 429226586Sdim T2 = T2ObjCPtrType->getPointeeType(); 430226586Sdim T1 = T1PtrType->getPointeeType(); 431226586Sdim return true; 432226586Sdim } 433226586Sdim } 434226586Sdim 435226586Sdim const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(), 436226586Sdim *T2MPType = T2->getAs<MemberPointerType>(); 437226586Sdim if (T1MPType && T2MPType) { 438226586Sdim T1 = T1MPType->getPointeeType(); 439226586Sdim T2 = T2MPType->getPointeeType(); 440226586Sdim return true; 441226586Sdim } 442226586Sdim 443226586Sdim const BlockPointerType *T1BPType = T1->getAs<BlockPointerType>(), 444226586Sdim *T2BPType = T2->getAs<BlockPointerType>(); 445226586Sdim if (T1BPType && T2BPType) { 446226586Sdim T1 = T1BPType->getPointeeType(); 447226586Sdim T2 = T2BPType->getPointeeType(); 448226586Sdim return true; 449226586Sdim } 450226586Sdim 451226586Sdim return false; 452226586Sdim} 453226586Sdim 454226586Sdim/// CastsAwayConstness - Check if the pointer conversion from SrcType to 455226586Sdim/// DestType casts away constness as defined in C++ 5.2.11p8ff. This is used by 456226586Sdim/// the cast checkers. Both arguments must denote pointer (possibly to member) 457226586Sdim/// types. 458226586Sdim/// 459226586Sdim/// \param CheckCVR Whether to check for const/volatile/restrict qualifiers. 460226586Sdim/// 461226586Sdim/// \param CheckObjCLifetime Whether to check Objective-C lifetime qualifiers. 462226586Sdimstatic bool 463226586SdimCastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, 464226586Sdim bool CheckCVR, bool CheckObjCLifetime) { 465226586Sdim // If the only checking we care about is for Objective-C lifetime qualifiers, 466226586Sdim // and we're not in ARC mode, there's nothing to check. 467226586Sdim if (!CheckCVR && CheckObjCLifetime && 468234353Sdim !Self.Context.getLangOpts().ObjCAutoRefCount) 469226586Sdim return false; 470226586Sdim 471226586Sdim // Casting away constness is defined in C++ 5.2.11p8 with reference to 472226586Sdim // C++ 4.4. We piggyback on Sema::IsQualificationConversion for this, since 473226586Sdim // the rules are non-trivial. So first we construct Tcv *...cv* as described 474226586Sdim // in C++ 5.2.11p8. 475226586Sdim assert((SrcType->isAnyPointerType() || SrcType->isMemberPointerType() || 476226586Sdim SrcType->isBlockPointerType()) && 477226586Sdim "Source type is not pointer or pointer to member."); 478226586Sdim assert((DestType->isAnyPointerType() || DestType->isMemberPointerType() || 479226586Sdim DestType->isBlockPointerType()) && 480226586Sdim "Destination type is not pointer or pointer to member."); 481226586Sdim 482226586Sdim QualType UnwrappedSrcType = Self.Context.getCanonicalType(SrcType), 483226586Sdim UnwrappedDestType = Self.Context.getCanonicalType(DestType); 484226586Sdim SmallVector<Qualifiers, 8> cv1, cv2; 485226586Sdim 486226586Sdim // Find the qualifiers. We only care about cvr-qualifiers for the 487226586Sdim // purpose of this check, because other qualifiers (address spaces, 488226586Sdim // Objective-C GC, etc.) are part of the type's identity. 489226586Sdim while (UnwrapDissimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) { 490226586Sdim // Determine the relevant qualifiers at this level. 491226586Sdim Qualifiers SrcQuals, DestQuals; 492226586Sdim Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals); 493226586Sdim Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals); 494226586Sdim 495226586Sdim Qualifiers RetainedSrcQuals, RetainedDestQuals; 496226586Sdim if (CheckCVR) { 497226586Sdim RetainedSrcQuals.setCVRQualifiers(SrcQuals.getCVRQualifiers()); 498226586Sdim RetainedDestQuals.setCVRQualifiers(DestQuals.getCVRQualifiers()); 499226586Sdim } 500226586Sdim 501226586Sdim if (CheckObjCLifetime && 502226586Sdim !DestQuals.compatiblyIncludesObjCLifetime(SrcQuals)) 503226586Sdim return true; 504226586Sdim 505226586Sdim cv1.push_back(RetainedSrcQuals); 506226586Sdim cv2.push_back(RetainedDestQuals); 507226586Sdim } 508226586Sdim if (cv1.empty()) 509226586Sdim return false; 510226586Sdim 511226586Sdim // Construct void pointers with those qualifiers (in reverse order of 512226586Sdim // unwrapping, of course). 513226586Sdim QualType SrcConstruct = Self.Context.VoidTy; 514226586Sdim QualType DestConstruct = Self.Context.VoidTy; 515226586Sdim ASTContext &Context = Self.Context; 516263508Sdim for (SmallVectorImpl<Qualifiers>::reverse_iterator i1 = cv1.rbegin(), 517263508Sdim i2 = cv2.rbegin(); 518226586Sdim i1 != cv1.rend(); ++i1, ++i2) { 519226586Sdim SrcConstruct 520226586Sdim = Context.getPointerType(Context.getQualifiedType(SrcConstruct, *i1)); 521226586Sdim DestConstruct 522226586Sdim = Context.getPointerType(Context.getQualifiedType(DestConstruct, *i2)); 523226586Sdim } 524226586Sdim 525226586Sdim // Test if they're compatible. 526226586Sdim bool ObjCLifetimeConversion; 527226586Sdim return SrcConstruct != DestConstruct && 528226586Sdim !Self.IsQualificationConversion(SrcConstruct, DestConstruct, false, 529226586Sdim ObjCLifetimeConversion); 530226586Sdim} 531226586Sdim 532226586Sdim/// CheckDynamicCast - Check that a dynamic_cast\<DestType\>(SrcExpr) is valid. 533226586Sdim/// Refer to C++ 5.2.7 for details. Dynamic casts are used mostly for runtime- 534226586Sdim/// checked downcasts in class hierarchies. 535226586Sdimvoid CastOperation::CheckDynamicCast() { 536234353Sdim if (ValueKind == VK_RValue) 537234353Sdim SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); 538234353Sdim else if (isPlaceholder()) 539234353Sdim SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take()); 540234353Sdim if (SrcExpr.isInvalid()) // if conversion failed, don't report another error 541234353Sdim return; 542234353Sdim 543226586Sdim QualType OrigSrcType = SrcExpr.get()->getType(); 544226586Sdim QualType DestType = Self.Context.getCanonicalType(this->DestType); 545226586Sdim 546226586Sdim // C++ 5.2.7p1: T shall be a pointer or reference to a complete class type, 547226586Sdim // or "pointer to cv void". 548226586Sdim 549226586Sdim QualType DestPointee; 550226586Sdim const PointerType *DestPointer = DestType->getAs<PointerType>(); 551226586Sdim const ReferenceType *DestReference = 0; 552226586Sdim if (DestPointer) { 553226586Sdim DestPointee = DestPointer->getPointeeType(); 554226586Sdim } else if ((DestReference = DestType->getAs<ReferenceType>())) { 555226586Sdim DestPointee = DestReference->getPointeeType(); 556226586Sdim } else { 557226586Sdim Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr) 558226586Sdim << this->DestType << DestRange; 559263508Sdim SrcExpr = ExprError(); 560226586Sdim return; 561226586Sdim } 562226586Sdim 563226586Sdim const RecordType *DestRecord = DestPointee->getAs<RecordType>(); 564226586Sdim if (DestPointee->isVoidType()) { 565226586Sdim assert(DestPointer && "Reference to void is not possible"); 566226586Sdim } else if (DestRecord) { 567226586Sdim if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee, 568239462Sdim diag::err_bad_dynamic_cast_incomplete, 569263508Sdim DestRange)) { 570263508Sdim SrcExpr = ExprError(); 571226586Sdim return; 572263508Sdim } 573226586Sdim } else { 574226586Sdim Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class) 575226586Sdim << DestPointee.getUnqualifiedType() << DestRange; 576263508Sdim SrcExpr = ExprError(); 577226586Sdim return; 578226586Sdim } 579226586Sdim 580226586Sdim // C++0x 5.2.7p2: If T is a pointer type, v shall be an rvalue of a pointer to 581226586Sdim // complete class type, [...]. If T is an lvalue reference type, v shall be 582226586Sdim // an lvalue of a complete class type, [...]. If T is an rvalue reference 583226586Sdim // type, v shall be an expression having a complete class type, [...] 584226586Sdim QualType SrcType = Self.Context.getCanonicalType(OrigSrcType); 585226586Sdim QualType SrcPointee; 586226586Sdim if (DestPointer) { 587226586Sdim if (const PointerType *SrcPointer = SrcType->getAs<PointerType>()) { 588226586Sdim SrcPointee = SrcPointer->getPointeeType(); 589226586Sdim } else { 590226586Sdim Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr) 591226586Sdim << OrigSrcType << SrcExpr.get()->getSourceRange(); 592263508Sdim SrcExpr = ExprError(); 593226586Sdim return; 594226586Sdim } 595226586Sdim } else if (DestReference->isLValueReferenceType()) { 596226586Sdim if (!SrcExpr.get()->isLValue()) { 597226586Sdim Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue) 598226586Sdim << CT_Dynamic << OrigSrcType << this->DestType << OpRange; 599226586Sdim } 600226586Sdim SrcPointee = SrcType; 601226586Sdim } else { 602226586Sdim SrcPointee = SrcType; 603226586Sdim } 604226586Sdim 605226586Sdim const RecordType *SrcRecord = SrcPointee->getAs<RecordType>(); 606226586Sdim if (SrcRecord) { 607226586Sdim if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee, 608239462Sdim diag::err_bad_dynamic_cast_incomplete, 609263508Sdim SrcExpr.get())) { 610263508Sdim SrcExpr = ExprError(); 611226586Sdim return; 612263508Sdim } 613226586Sdim } else { 614226586Sdim Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class) 615226586Sdim << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange(); 616263508Sdim SrcExpr = ExprError(); 617226586Sdim return; 618226586Sdim } 619226586Sdim 620226586Sdim assert((DestPointer || DestReference) && 621226586Sdim "Bad destination non-ptr/ref slipped through."); 622226586Sdim assert((DestRecord || DestPointee->isVoidType()) && 623226586Sdim "Bad destination pointee slipped through."); 624226586Sdim assert(SrcRecord && "Bad source pointee slipped through."); 625226586Sdim 626226586Sdim // C++ 5.2.7p1: The dynamic_cast operator shall not cast away constness. 627226586Sdim if (!DestPointee.isAtLeastAsQualifiedAs(SrcPointee)) { 628226586Sdim Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away) 629226586Sdim << CT_Dynamic << OrigSrcType << this->DestType << OpRange; 630263508Sdim SrcExpr = ExprError(); 631226586Sdim return; 632226586Sdim } 633226586Sdim 634226586Sdim // C++ 5.2.7p3: If the type of v is the same as the required result type, 635226586Sdim // [except for cv]. 636226586Sdim if (DestRecord == SrcRecord) { 637226586Sdim Kind = CK_NoOp; 638226586Sdim return; 639226586Sdim } 640226586Sdim 641226586Sdim // C++ 5.2.7p5 642226586Sdim // Upcasts are resolved statically. 643226586Sdim if (DestRecord && Self.IsDerivedFrom(SrcPointee, DestPointee)) { 644226586Sdim if (Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee, 645226586Sdim OpRange.getBegin(), OpRange, 646263508Sdim &BasePath)) { 647263508Sdim SrcExpr = ExprError(); 648263508Sdim return; 649263508Sdim } 650226586Sdim 651226586Sdim Kind = CK_DerivedToBase; 652226586Sdim 653226586Sdim // If we are casting to or through a virtual base class, we need a 654226586Sdim // vtable. 655226586Sdim if (Self.BasePathInvolvesVirtualBase(BasePath)) 656226586Sdim Self.MarkVTableUsed(OpRange.getBegin(), 657226586Sdim cast<CXXRecordDecl>(SrcRecord->getDecl())); 658226586Sdim return; 659226586Sdim } 660226586Sdim 661226586Sdim // C++ 5.2.7p6: Otherwise, v shall be [polymorphic]. 662226586Sdim const RecordDecl *SrcDecl = SrcRecord->getDecl()->getDefinition(); 663226586Sdim assert(SrcDecl && "Definition missing"); 664226586Sdim if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) { 665226586Sdim Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic) 666226586Sdim << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange(); 667263508Sdim SrcExpr = ExprError(); 668226586Sdim } 669226586Sdim Self.MarkVTableUsed(OpRange.getBegin(), 670226586Sdim cast<CXXRecordDecl>(SrcRecord->getDecl())); 671226586Sdim 672263508Sdim // dynamic_cast is not available with -fno-rtti. 673263508Sdim // As an exception, dynamic_cast to void* is available because it doesn't 674263508Sdim // use RTTI. 675263508Sdim if (!Self.getLangOpts().RTTI && !DestPointee->isVoidType()) { 676263508Sdim Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti); 677263508Sdim SrcExpr = ExprError(); 678263508Sdim return; 679263508Sdim } 680263508Sdim 681226586Sdim // Done. Everything else is run-time checks. 682226586Sdim Kind = CK_Dynamic; 683226586Sdim} 684226586Sdim 685226586Sdim/// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid. 686226586Sdim/// Refer to C++ 5.2.11 for details. const_cast is typically used in code 687226586Sdim/// like this: 688226586Sdim/// const char *str = "literal"; 689226586Sdim/// legacy_function(const_cast\<char*\>(str)); 690226586Sdimvoid CastOperation::CheckConstCast() { 691234353Sdim if (ValueKind == VK_RValue) 692226586Sdim SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); 693234353Sdim else if (isPlaceholder()) 694234353Sdim SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take()); 695234353Sdim if (SrcExpr.isInvalid()) // if conversion failed, don't report another error 696234353Sdim return; 697226586Sdim 698226586Sdim unsigned msg = diag::err_bad_cxx_cast_generic; 699263508Sdim if (TryConstCast(Self, SrcExpr, DestType, /*CStyle*/false, msg) != TC_Success 700263508Sdim && msg != 0) { 701226586Sdim Self.Diag(OpRange.getBegin(), msg) << CT_Const 702226586Sdim << SrcExpr.get()->getType() << DestType << OpRange; 703263508Sdim SrcExpr = ExprError(); 704263508Sdim } 705226586Sdim} 706226586Sdim 707249423Sdim/// Check that a reinterpret_cast\<DestType\>(SrcExpr) is not used as upcast 708249423Sdim/// or downcast between respective pointers or references. 709249423Sdimstatic void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr, 710249423Sdim QualType DestType, 711249423Sdim SourceRange OpRange) { 712249423Sdim QualType SrcType = SrcExpr->getType(); 713249423Sdim // When casting from pointer or reference, get pointee type; use original 714249423Sdim // type otherwise. 715249423Sdim const CXXRecordDecl *SrcPointeeRD = SrcType->getPointeeCXXRecordDecl(); 716249423Sdim const CXXRecordDecl *SrcRD = 717249423Sdim SrcPointeeRD ? SrcPointeeRD : SrcType->getAsCXXRecordDecl(); 718249423Sdim 719249423Sdim // Examining subobjects for records is only possible if the complete and 720249423Sdim // valid definition is available. Also, template instantiation is not 721249423Sdim // allowed here. 722249423Sdim if (!SrcRD || !SrcRD->isCompleteDefinition() || SrcRD->isInvalidDecl()) 723249423Sdim return; 724249423Sdim 725249423Sdim const CXXRecordDecl *DestRD = DestType->getPointeeCXXRecordDecl(); 726249423Sdim 727249423Sdim if (!DestRD || !DestRD->isCompleteDefinition() || DestRD->isInvalidDecl()) 728249423Sdim return; 729249423Sdim 730249423Sdim enum { 731249423Sdim ReinterpretUpcast, 732249423Sdim ReinterpretDowncast 733249423Sdim } ReinterpretKind; 734249423Sdim 735249423Sdim CXXBasePaths BasePaths; 736249423Sdim 737249423Sdim if (SrcRD->isDerivedFrom(DestRD, BasePaths)) 738249423Sdim ReinterpretKind = ReinterpretUpcast; 739249423Sdim else if (DestRD->isDerivedFrom(SrcRD, BasePaths)) 740249423Sdim ReinterpretKind = ReinterpretDowncast; 741249423Sdim else 742249423Sdim return; 743249423Sdim 744249423Sdim bool VirtualBase = true; 745249423Sdim bool NonZeroOffset = false; 746249423Sdim for (CXXBasePaths::const_paths_iterator I = BasePaths.begin(), 747249423Sdim E = BasePaths.end(); 748249423Sdim I != E; ++I) { 749249423Sdim const CXXBasePath &Path = *I; 750249423Sdim CharUnits Offset = CharUnits::Zero(); 751249423Sdim bool IsVirtual = false; 752249423Sdim for (CXXBasePath::const_iterator IElem = Path.begin(), EElem = Path.end(); 753249423Sdim IElem != EElem; ++IElem) { 754249423Sdim IsVirtual = IElem->Base->isVirtual(); 755249423Sdim if (IsVirtual) 756249423Sdim break; 757249423Sdim const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl(); 758249423Sdim assert(BaseRD && "Base type should be a valid unqualified class type"); 759249423Sdim // Don't check if any base has invalid declaration or has no definition 760249423Sdim // since it has no layout info. 761249423Sdim const CXXRecordDecl *Class = IElem->Class, 762249423Sdim *ClassDefinition = Class->getDefinition(); 763249423Sdim if (Class->isInvalidDecl() || !ClassDefinition || 764249423Sdim !ClassDefinition->isCompleteDefinition()) 765249423Sdim return; 766249423Sdim 767249423Sdim const ASTRecordLayout &DerivedLayout = 768249423Sdim Self.Context.getASTRecordLayout(Class); 769249423Sdim Offset += DerivedLayout.getBaseClassOffset(BaseRD); 770249423Sdim } 771249423Sdim if (!IsVirtual) { 772249423Sdim // Don't warn if any path is a non-virtually derived base at offset zero. 773249423Sdim if (Offset.isZero()) 774249423Sdim return; 775249423Sdim // Offset makes sense only for non-virtual bases. 776249423Sdim else 777249423Sdim NonZeroOffset = true; 778249423Sdim } 779249423Sdim VirtualBase = VirtualBase && IsVirtual; 780249423Sdim } 781249423Sdim 782263508Sdim (void) NonZeroOffset; // Silence set but not used warning. 783249423Sdim assert((VirtualBase || NonZeroOffset) && 784249423Sdim "Should have returned if has non-virtual base with zero offset"); 785249423Sdim 786249423Sdim QualType BaseType = 787249423Sdim ReinterpretKind == ReinterpretUpcast? DestType : SrcType; 788249423Sdim QualType DerivedType = 789249423Sdim ReinterpretKind == ReinterpretUpcast? SrcType : DestType; 790249423Sdim 791249423Sdim SourceLocation BeginLoc = OpRange.getBegin(); 792249423Sdim Self.Diag(BeginLoc, diag::warn_reinterpret_different_from_static) 793263508Sdim << DerivedType << BaseType << !VirtualBase << int(ReinterpretKind) 794249423Sdim << OpRange; 795249423Sdim Self.Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static) 796263508Sdim << int(ReinterpretKind) 797249423Sdim << FixItHint::CreateReplacement(BeginLoc, "static_cast"); 798249423Sdim} 799249423Sdim 800226586Sdim/// CheckReinterpretCast - Check that a reinterpret_cast\<DestType\>(SrcExpr) is 801226586Sdim/// valid. 802226586Sdim/// Refer to C++ 5.2.10 for details. reinterpret_cast is typically used in code 803226586Sdim/// like this: 804226586Sdim/// char *bytes = reinterpret_cast\<char*\>(int_ptr); 805226586Sdimvoid CastOperation::CheckReinterpretCast() { 806234353Sdim if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload)) 807226586Sdim SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); 808234353Sdim else 809234353Sdim checkNonOverloadPlaceholders(); 810234353Sdim if (SrcExpr.isInvalid()) // if conversion failed, don't report another error 811234353Sdim return; 812226586Sdim 813226586Sdim unsigned msg = diag::err_bad_cxx_cast_generic; 814226586Sdim TryCastResult tcr = 815226586Sdim TryReinterpretCast(Self, SrcExpr, DestType, 816226586Sdim /*CStyle*/false, OpRange, msg, Kind); 817226586Sdim if (tcr != TC_Success && msg != 0) 818226586Sdim { 819226586Sdim if (SrcExpr.isInvalid()) // if conversion failed, don't report another error 820226586Sdim return; 821226586Sdim if (SrcExpr.get()->getType() == Self.Context.OverloadTy) { 822226586Sdim //FIXME: &f<int>; is overloaded and resolvable 823226586Sdim Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload) 824226586Sdim << OverloadExpr::find(SrcExpr.get()).Expression->getName() 825226586Sdim << DestType << OpRange; 826226586Sdim Self.NoteAllOverloadCandidates(SrcExpr.get()); 827226586Sdim 828226586Sdim } else { 829234353Sdim diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(), 830234353Sdim DestType, /*listInitialization=*/false); 831226586Sdim } 832263508Sdim SrcExpr = ExprError(); 833249423Sdim } else if (tcr == TC_Success) { 834249423Sdim if (Self.getLangOpts().ObjCAutoRefCount) 835249423Sdim checkObjCARCConversion(Sema::CCK_OtherCast); 836249423Sdim DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange); 837226586Sdim } 838226586Sdim} 839226586Sdim 840226586Sdim 841226586Sdim/// CheckStaticCast - Check that a static_cast\<DestType\>(SrcExpr) is valid. 842226586Sdim/// Refer to C++ 5.2.9 for details. Static casts are mostly used for making 843226586Sdim/// implicit conversions explicit and getting rid of data loss warnings. 844226586Sdimvoid CastOperation::CheckStaticCast() { 845226586Sdim if (isPlaceholder()) { 846226586Sdim checkNonOverloadPlaceholders(); 847226586Sdim if (SrcExpr.isInvalid()) 848226586Sdim return; 849226586Sdim } 850226586Sdim 851226586Sdim // This test is outside everything else because it's the only case where 852226586Sdim // a non-lvalue-reference target type does not lead to decay. 853226586Sdim // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". 854226586Sdim if (DestType->isVoidType()) { 855226586Sdim Kind = CK_ToVoid; 856226586Sdim 857226586Sdim if (claimPlaceholder(BuiltinType::Overload)) { 858226586Sdim Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr, 859226586Sdim false, // Decay Function to ptr 860226586Sdim true, // Complain 861226586Sdim OpRange, DestType, diag::err_bad_static_cast_overload); 862226586Sdim if (SrcExpr.isInvalid()) 863226586Sdim return; 864226586Sdim } 865226586Sdim 866226586Sdim SrcExpr = Self.IgnoredValueConversions(SrcExpr.take()); 867226586Sdim return; 868226586Sdim } 869226586Sdim 870226586Sdim if (ValueKind == VK_RValue && !DestType->isRecordType() && 871226586Sdim !isPlaceholder(BuiltinType::Overload)) { 872226586Sdim SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); 873226586Sdim if (SrcExpr.isInvalid()) // if conversion failed, don't report another error 874226586Sdim return; 875226586Sdim } 876226586Sdim 877226586Sdim unsigned msg = diag::err_bad_cxx_cast_generic; 878226586Sdim TryCastResult tcr 879226586Sdim = TryStaticCast(Self, SrcExpr, DestType, Sema::CCK_OtherCast, OpRange, msg, 880234353Sdim Kind, BasePath, /*ListInitialization=*/false); 881226586Sdim if (tcr != TC_Success && msg != 0) { 882226586Sdim if (SrcExpr.isInvalid()) 883226586Sdim return; 884226586Sdim if (SrcExpr.get()->getType() == Self.Context.OverloadTy) { 885226586Sdim OverloadExpr* oe = OverloadExpr::find(SrcExpr.get()).Expression; 886226586Sdim Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload) 887226586Sdim << oe->getName() << DestType << OpRange 888226586Sdim << oe->getQualifierLoc().getSourceRange(); 889226586Sdim Self.NoteAllOverloadCandidates(SrcExpr.get()); 890226586Sdim } else { 891234353Sdim diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr.get(), DestType, 892234353Sdim /*listInitialization=*/false); 893226586Sdim } 894263508Sdim SrcExpr = ExprError(); 895226586Sdim } else if (tcr == TC_Success) { 896226586Sdim if (Kind == CK_BitCast) 897226586Sdim checkCastAlign(); 898234353Sdim if (Self.getLangOpts().ObjCAutoRefCount) 899226586Sdim checkObjCARCConversion(Sema::CCK_OtherCast); 900226586Sdim } else if (Kind == CK_BitCast) { 901226586Sdim checkCastAlign(); 902226586Sdim } 903226586Sdim} 904226586Sdim 905226586Sdim/// TryStaticCast - Check if a static cast can be performed, and do so if 906226586Sdim/// possible. If @p CStyle, ignore access restrictions on hierarchy casting 907226586Sdim/// and casting away constness. 908226586Sdimstatic TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, 909226586Sdim QualType DestType, 910226586Sdim Sema::CheckedConversionKind CCK, 911226586Sdim const SourceRange &OpRange, unsigned &msg, 912234353Sdim CastKind &Kind, CXXCastPath &BasePath, 913234353Sdim bool ListInitialization) { 914226586Sdim // Determine whether we have the semantics of a C-style cast. 915226586Sdim bool CStyle 916226586Sdim = (CCK == Sema::CCK_CStyleCast || CCK == Sema::CCK_FunctionalCast); 917226586Sdim 918226586Sdim // The order the tests is not entirely arbitrary. There is one conversion 919226586Sdim // that can be handled in two different ways. Given: 920226586Sdim // struct A {}; 921226586Sdim // struct B : public A { 922226586Sdim // B(); B(const A&); 923226586Sdim // }; 924226586Sdim // const A &a = B(); 925226586Sdim // the cast static_cast<const B&>(a) could be seen as either a static 926226586Sdim // reference downcast, or an explicit invocation of the user-defined 927226586Sdim // conversion using B's conversion constructor. 928226586Sdim // DR 427 specifies that the downcast is to be applied here. 929226586Sdim 930226586Sdim // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". 931226586Sdim // Done outside this function. 932226586Sdim 933226586Sdim TryCastResult tcr; 934226586Sdim 935226586Sdim // C++ 5.2.9p5, reference downcast. 936226586Sdim // See the function for details. 937226586Sdim // DR 427 specifies that this is to be applied before paragraph 2. 938234353Sdim tcr = TryStaticReferenceDowncast(Self, SrcExpr.get(), DestType, CStyle, 939234353Sdim OpRange, msg, Kind, BasePath); 940226586Sdim if (tcr != TC_NotApplicable) 941226586Sdim return tcr; 942226586Sdim 943226586Sdim // C++0x [expr.static.cast]p3: 944226586Sdim // A glvalue of type "cv1 T1" can be cast to type "rvalue reference to cv2 945226586Sdim // T2" if "cv2 T2" is reference-compatible with "cv1 T1". 946234353Sdim tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, Kind, 947234353Sdim BasePath, msg); 948226586Sdim if (tcr != TC_NotApplicable) 949226586Sdim return tcr; 950226586Sdim 951226586Sdim // C++ 5.2.9p2: An expression e can be explicitly converted to a type T 952226586Sdim // [...] if the declaration "T t(e);" is well-formed, [...]. 953226586Sdim tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CCK, OpRange, msg, 954234353Sdim Kind, ListInitialization); 955226586Sdim if (SrcExpr.isInvalid()) 956226586Sdim return TC_Failed; 957226586Sdim if (tcr != TC_NotApplicable) 958226586Sdim return tcr; 959226586Sdim 960226586Sdim // C++ 5.2.9p6: May apply the reverse of any standard conversion, except 961226586Sdim // lvalue-to-rvalue, array-to-pointer, function-to-pointer, and boolean 962226586Sdim // conversions, subject to further restrictions. 963226586Sdim // Also, C++ 5.2.9p1 forbids casting away constness, which makes reversal 964226586Sdim // of qualification conversions impossible. 965226586Sdim // In the CStyle case, the earlier attempt to const_cast should have taken 966226586Sdim // care of reverse qualification conversions. 967226586Sdim 968226586Sdim QualType SrcType = Self.Context.getCanonicalType(SrcExpr.get()->getType()); 969226586Sdim 970226586Sdim // C++0x 5.2.9p9: A value of a scoped enumeration type can be explicitly 971226586Sdim // converted to an integral type. [...] A value of a scoped enumeration type 972226586Sdim // can also be explicitly converted to a floating-point type [...]. 973226586Sdim if (const EnumType *Enum = SrcType->getAs<EnumType>()) { 974226586Sdim if (Enum->getDecl()->isScoped()) { 975226586Sdim if (DestType->isBooleanType()) { 976226586Sdim Kind = CK_IntegralToBoolean; 977226586Sdim return TC_Success; 978226586Sdim } else if (DestType->isIntegralType(Self.Context)) { 979226586Sdim Kind = CK_IntegralCast; 980226586Sdim return TC_Success; 981226586Sdim } else if (DestType->isRealFloatingType()) { 982226586Sdim Kind = CK_IntegralToFloating; 983226586Sdim return TC_Success; 984226586Sdim } 985226586Sdim } 986226586Sdim } 987226586Sdim 988226586Sdim // Reverse integral promotion/conversion. All such conversions are themselves 989226586Sdim // again integral promotions or conversions and are thus already handled by 990226586Sdim // p2 (TryDirectInitialization above). 991226586Sdim // (Note: any data loss warnings should be suppressed.) 992226586Sdim // The exception is the reverse of enum->integer, i.e. integer->enum (and 993226586Sdim // enum->enum). See also C++ 5.2.9p7. 994226586Sdim // The same goes for reverse floating point promotion/conversion and 995226586Sdim // floating-integral conversions. Again, only floating->enum is relevant. 996226586Sdim if (DestType->isEnumeralType()) { 997226586Sdim if (SrcType->isIntegralOrEnumerationType()) { 998226586Sdim Kind = CK_IntegralCast; 999226586Sdim return TC_Success; 1000226586Sdim } else if (SrcType->isRealFloatingType()) { 1001226586Sdim Kind = CK_FloatingToIntegral; 1002226586Sdim return TC_Success; 1003226586Sdim } 1004226586Sdim } 1005226586Sdim 1006226586Sdim // Reverse pointer upcast. C++ 4.10p3 specifies pointer upcast. 1007226586Sdim // C++ 5.2.9p8 additionally disallows a cast path through virtual inheritance. 1008226586Sdim tcr = TryStaticPointerDowncast(Self, SrcType, DestType, CStyle, OpRange, msg, 1009226586Sdim Kind, BasePath); 1010226586Sdim if (tcr != TC_NotApplicable) 1011226586Sdim return tcr; 1012226586Sdim 1013226586Sdim // Reverse member pointer conversion. C++ 4.11 specifies member pointer 1014226586Sdim // conversion. C++ 5.2.9p9 has additional information. 1015226586Sdim // DR54's access restrictions apply here also. 1016226586Sdim tcr = TryStaticMemberPointerUpcast(Self, SrcExpr, SrcType, DestType, CStyle, 1017226586Sdim OpRange, msg, Kind, BasePath); 1018226586Sdim if (tcr != TC_NotApplicable) 1019226586Sdim return tcr; 1020226586Sdim 1021226586Sdim // Reverse pointer conversion to void*. C++ 4.10.p2 specifies conversion to 1022226586Sdim // void*. C++ 5.2.9p10 specifies additional restrictions, which really is 1023226586Sdim // just the usual constness stuff. 1024226586Sdim if (const PointerType *SrcPointer = SrcType->getAs<PointerType>()) { 1025226586Sdim QualType SrcPointee = SrcPointer->getPointeeType(); 1026226586Sdim if (SrcPointee->isVoidType()) { 1027226586Sdim if (const PointerType *DestPointer = DestType->getAs<PointerType>()) { 1028226586Sdim QualType DestPointee = DestPointer->getPointeeType(); 1029226586Sdim if (DestPointee->isIncompleteOrObjectType()) { 1030226586Sdim // This is definitely the intended conversion, but it might fail due 1031226586Sdim // to a qualifier violation. Note that we permit Objective-C lifetime 1032226586Sdim // and GC qualifier mismatches here. 1033226586Sdim if (!CStyle) { 1034226586Sdim Qualifiers DestPointeeQuals = DestPointee.getQualifiers(); 1035226586Sdim Qualifiers SrcPointeeQuals = SrcPointee.getQualifiers(); 1036226586Sdim DestPointeeQuals.removeObjCGCAttr(); 1037226586Sdim DestPointeeQuals.removeObjCLifetime(); 1038226586Sdim SrcPointeeQuals.removeObjCGCAttr(); 1039226586Sdim SrcPointeeQuals.removeObjCLifetime(); 1040226586Sdim if (DestPointeeQuals != SrcPointeeQuals && 1041226586Sdim !DestPointeeQuals.compatiblyIncludes(SrcPointeeQuals)) { 1042226586Sdim msg = diag::err_bad_cxx_cast_qualifiers_away; 1043226586Sdim return TC_Failed; 1044226586Sdim } 1045226586Sdim } 1046226586Sdim Kind = CK_BitCast; 1047226586Sdim return TC_Success; 1048226586Sdim } 1049226586Sdim } 1050226586Sdim else if (DestType->isObjCObjectPointerType()) { 1051226586Sdim // allow both c-style cast and static_cast of objective-c pointers as 1052226586Sdim // they are pervasive. 1053226586Sdim Kind = CK_CPointerToObjCPointerCast; 1054226586Sdim return TC_Success; 1055226586Sdim } 1056226586Sdim else if (CStyle && DestType->isBlockPointerType()) { 1057226586Sdim // allow c-style cast of void * to block pointers. 1058226586Sdim Kind = CK_AnyPointerToBlockPointerCast; 1059226586Sdim return TC_Success; 1060226586Sdim } 1061226586Sdim } 1062226586Sdim } 1063226586Sdim // Allow arbitray objective-c pointer conversion with static casts. 1064226586Sdim if (SrcType->isObjCObjectPointerType() && 1065226586Sdim DestType->isObjCObjectPointerType()) { 1066226586Sdim Kind = CK_BitCast; 1067226586Sdim return TC_Success; 1068226586Sdim } 1069226586Sdim 1070226586Sdim // We tried everything. Everything! Nothing works! :-( 1071226586Sdim return TC_NotApplicable; 1072226586Sdim} 1073226586Sdim 1074226586Sdim/// Tests whether a conversion according to N2844 is valid. 1075226586SdimTryCastResult 1076226586SdimTryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType, 1077226586Sdim bool CStyle, CastKind &Kind, CXXCastPath &BasePath, 1078226586Sdim unsigned &msg) { 1079226586Sdim // C++0x [expr.static.cast]p3: 1080226586Sdim // A glvalue of type "cv1 T1" can be cast to type "rvalue reference to 1081226586Sdim // cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1". 1082226586Sdim const RValueReferenceType *R = DestType->getAs<RValueReferenceType>(); 1083226586Sdim if (!R) 1084226586Sdim return TC_NotApplicable; 1085226586Sdim 1086226586Sdim if (!SrcExpr->isGLValue()) 1087226586Sdim return TC_NotApplicable; 1088226586Sdim 1089226586Sdim // Because we try the reference downcast before this function, from now on 1090226586Sdim // this is the only cast possibility, so we issue an error if we fail now. 1091226586Sdim // FIXME: Should allow casting away constness if CStyle. 1092226586Sdim bool DerivedToBase; 1093226586Sdim bool ObjCConversion; 1094226586Sdim bool ObjCLifetimeConversion; 1095226586Sdim QualType FromType = SrcExpr->getType(); 1096226586Sdim QualType ToType = R->getPointeeType(); 1097226586Sdim if (CStyle) { 1098226586Sdim FromType = FromType.getUnqualifiedType(); 1099226586Sdim ToType = ToType.getUnqualifiedType(); 1100226586Sdim } 1101226586Sdim 1102226586Sdim if (Self.CompareReferenceRelationship(SrcExpr->getLocStart(), 1103226586Sdim ToType, FromType, 1104226586Sdim DerivedToBase, ObjCConversion, 1105226586Sdim ObjCLifetimeConversion) 1106226586Sdim < Sema::Ref_Compatible_With_Added_Qualification) { 1107226586Sdim msg = diag::err_bad_lvalue_to_rvalue_cast; 1108226586Sdim return TC_Failed; 1109226586Sdim } 1110226586Sdim 1111226586Sdim if (DerivedToBase) { 1112226586Sdim Kind = CK_DerivedToBase; 1113226586Sdim CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 1114226586Sdim /*DetectVirtual=*/true); 1115226586Sdim if (!Self.IsDerivedFrom(SrcExpr->getType(), R->getPointeeType(), Paths)) 1116226586Sdim return TC_NotApplicable; 1117226586Sdim 1118226586Sdim Self.BuildBasePathArray(Paths, BasePath); 1119226586Sdim } else 1120226586Sdim Kind = CK_NoOp; 1121226586Sdim 1122226586Sdim return TC_Success; 1123226586Sdim} 1124226586Sdim 1125226586Sdim/// Tests whether a conversion according to C++ 5.2.9p5 is valid. 1126226586SdimTryCastResult 1127226586SdimTryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType, 1128226586Sdim bool CStyle, const SourceRange &OpRange, 1129226586Sdim unsigned &msg, CastKind &Kind, 1130226586Sdim CXXCastPath &BasePath) { 1131226586Sdim // C++ 5.2.9p5: An lvalue of type "cv1 B", where B is a class type, can be 1132226586Sdim // cast to type "reference to cv2 D", where D is a class derived from B, 1133226586Sdim // if a valid standard conversion from "pointer to D" to "pointer to B" 1134226586Sdim // exists, cv2 >= cv1, and B is not a virtual base class of D. 1135226586Sdim // In addition, DR54 clarifies that the base must be accessible in the 1136226586Sdim // current context. Although the wording of DR54 only applies to the pointer 1137226586Sdim // variant of this rule, the intent is clearly for it to apply to the this 1138226586Sdim // conversion as well. 1139226586Sdim 1140226586Sdim const ReferenceType *DestReference = DestType->getAs<ReferenceType>(); 1141226586Sdim if (!DestReference) { 1142226586Sdim return TC_NotApplicable; 1143226586Sdim } 1144226586Sdim bool RValueRef = DestReference->isRValueReferenceType(); 1145226586Sdim if (!RValueRef && !SrcExpr->isLValue()) { 1146226586Sdim // We know the left side is an lvalue reference, so we can suggest a reason. 1147226586Sdim msg = diag::err_bad_cxx_cast_rvalue; 1148226586Sdim return TC_NotApplicable; 1149226586Sdim } 1150226586Sdim 1151226586Sdim QualType DestPointee = DestReference->getPointeeType(); 1152226586Sdim 1153226586Sdim return TryStaticDowncast(Self, 1154226586Sdim Self.Context.getCanonicalType(SrcExpr->getType()), 1155226586Sdim Self.Context.getCanonicalType(DestPointee), CStyle, 1156226586Sdim OpRange, SrcExpr->getType(), DestType, msg, Kind, 1157226586Sdim BasePath); 1158226586Sdim} 1159226586Sdim 1160226586Sdim/// Tests whether a conversion according to C++ 5.2.9p8 is valid. 1161226586SdimTryCastResult 1162226586SdimTryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType, 1163226586Sdim bool CStyle, const SourceRange &OpRange, 1164226586Sdim unsigned &msg, CastKind &Kind, 1165226586Sdim CXXCastPath &BasePath) { 1166226586Sdim // C++ 5.2.9p8: An rvalue of type "pointer to cv1 B", where B is a class 1167226586Sdim // type, can be converted to an rvalue of type "pointer to cv2 D", where D 1168226586Sdim // is a class derived from B, if a valid standard conversion from "pointer 1169226586Sdim // to D" to "pointer to B" exists, cv2 >= cv1, and B is not a virtual base 1170226586Sdim // class of D. 1171226586Sdim // In addition, DR54 clarifies that the base must be accessible in the 1172226586Sdim // current context. 1173226586Sdim 1174226586Sdim const PointerType *DestPointer = DestType->getAs<PointerType>(); 1175226586Sdim if (!DestPointer) { 1176226586Sdim return TC_NotApplicable; 1177226586Sdim } 1178226586Sdim 1179226586Sdim const PointerType *SrcPointer = SrcType->getAs<PointerType>(); 1180226586Sdim if (!SrcPointer) { 1181226586Sdim msg = diag::err_bad_static_cast_pointer_nonpointer; 1182226586Sdim return TC_NotApplicable; 1183226586Sdim } 1184226586Sdim 1185226586Sdim return TryStaticDowncast(Self, 1186226586Sdim Self.Context.getCanonicalType(SrcPointer->getPointeeType()), 1187226586Sdim Self.Context.getCanonicalType(DestPointer->getPointeeType()), 1188226586Sdim CStyle, OpRange, SrcType, DestType, msg, Kind, 1189226586Sdim BasePath); 1190226586Sdim} 1191226586Sdim 1192226586Sdim/// TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and 1193226586Sdim/// TryStaticPointerDowncast. Tests whether a static downcast from SrcType to 1194226586Sdim/// DestType is possible and allowed. 1195226586SdimTryCastResult 1196226586SdimTryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, 1197226586Sdim bool CStyle, const SourceRange &OpRange, QualType OrigSrcType, 1198226586Sdim QualType OrigDestType, unsigned &msg, 1199226586Sdim CastKind &Kind, CXXCastPath &BasePath) { 1200226586Sdim // We can only work with complete types. But don't complain if it doesn't work 1201239462Sdim if (Self.RequireCompleteType(OpRange.getBegin(), SrcType, 0) || 1202239462Sdim Self.RequireCompleteType(OpRange.getBegin(), DestType, 0)) 1203226586Sdim return TC_NotApplicable; 1204226586Sdim 1205226586Sdim // Downcast can only happen in class hierarchies, so we need classes. 1206226586Sdim if (!DestType->getAs<RecordType>() || !SrcType->getAs<RecordType>()) { 1207226586Sdim return TC_NotApplicable; 1208226586Sdim } 1209226586Sdim 1210226586Sdim CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 1211226586Sdim /*DetectVirtual=*/true); 1212226586Sdim if (!Self.IsDerivedFrom(DestType, SrcType, Paths)) { 1213226586Sdim return TC_NotApplicable; 1214226586Sdim } 1215226586Sdim 1216226586Sdim // Target type does derive from source type. Now we're serious. If an error 1217226586Sdim // appears now, it's not ignored. 1218226586Sdim // This may not be entirely in line with the standard. Take for example: 1219226586Sdim // struct A {}; 1220226586Sdim // struct B : virtual A { 1221226586Sdim // B(A&); 1222226586Sdim // }; 1223226586Sdim // 1224226586Sdim // void f() 1225226586Sdim // { 1226226586Sdim // (void)static_cast<const B&>(*((A*)0)); 1227226586Sdim // } 1228226586Sdim // As far as the standard is concerned, p5 does not apply (A is virtual), so 1229226586Sdim // p2 should be used instead - "const B& t(*((A*)0));" is perfectly valid. 1230226586Sdim // However, both GCC and Comeau reject this example, and accepting it would 1231226586Sdim // mean more complex code if we're to preserve the nice error message. 1232226586Sdim // FIXME: Being 100% compliant here would be nice to have. 1233226586Sdim 1234226586Sdim // Must preserve cv, as always, unless we're in C-style mode. 1235226586Sdim if (!CStyle && !DestType.isAtLeastAsQualifiedAs(SrcType)) { 1236226586Sdim msg = diag::err_bad_cxx_cast_qualifiers_away; 1237226586Sdim return TC_Failed; 1238226586Sdim } 1239226586Sdim 1240226586Sdim if (Paths.isAmbiguous(SrcType.getUnqualifiedType())) { 1241226586Sdim // This code is analoguous to that in CheckDerivedToBaseConversion, except 1242226586Sdim // that it builds the paths in reverse order. 1243226586Sdim // To sum up: record all paths to the base and build a nice string from 1244226586Sdim // them. Use it to spice up the error message. 1245226586Sdim if (!Paths.isRecordingPaths()) { 1246226586Sdim Paths.clear(); 1247226586Sdim Paths.setRecordingPaths(true); 1248226586Sdim Self.IsDerivedFrom(DestType, SrcType, Paths); 1249226586Sdim } 1250226586Sdim std::string PathDisplayStr; 1251226586Sdim std::set<unsigned> DisplayedPaths; 1252226586Sdim for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end(); 1253226586Sdim PI != PE; ++PI) { 1254226586Sdim if (DisplayedPaths.insert(PI->back().SubobjectNumber).second) { 1255226586Sdim // We haven't displayed a path to this particular base 1256226586Sdim // class subobject yet. 1257226586Sdim PathDisplayStr += "\n "; 1258226586Sdim for (CXXBasePath::const_reverse_iterator EI = PI->rbegin(), 1259226586Sdim EE = PI->rend(); 1260226586Sdim EI != EE; ++EI) 1261226586Sdim PathDisplayStr += EI->Base->getType().getAsString() + " -> "; 1262226586Sdim PathDisplayStr += QualType(DestType).getAsString(); 1263226586Sdim } 1264226586Sdim } 1265226586Sdim 1266226586Sdim Self.Diag(OpRange.getBegin(), diag::err_ambiguous_base_to_derived_cast) 1267226586Sdim << QualType(SrcType).getUnqualifiedType() 1268226586Sdim << QualType(DestType).getUnqualifiedType() 1269226586Sdim << PathDisplayStr << OpRange; 1270226586Sdim msg = 0; 1271226586Sdim return TC_Failed; 1272226586Sdim } 1273226586Sdim 1274226586Sdim if (Paths.getDetectedVirtual() != 0) { 1275226586Sdim QualType VirtualBase(Paths.getDetectedVirtual(), 0); 1276226586Sdim Self.Diag(OpRange.getBegin(), diag::err_static_downcast_via_virtual) 1277226586Sdim << OrigSrcType << OrigDestType << VirtualBase << OpRange; 1278226586Sdim msg = 0; 1279226586Sdim return TC_Failed; 1280226586Sdim } 1281226586Sdim 1282226586Sdim if (!CStyle) { 1283226586Sdim switch (Self.CheckBaseClassAccess(OpRange.getBegin(), 1284226586Sdim SrcType, DestType, 1285226586Sdim Paths.front(), 1286226586Sdim diag::err_downcast_from_inaccessible_base)) { 1287226586Sdim case Sema::AR_accessible: 1288226586Sdim case Sema::AR_delayed: // be optimistic 1289226586Sdim case Sema::AR_dependent: // be optimistic 1290226586Sdim break; 1291226586Sdim 1292226586Sdim case Sema::AR_inaccessible: 1293226586Sdim msg = 0; 1294226586Sdim return TC_Failed; 1295226586Sdim } 1296226586Sdim } 1297226586Sdim 1298226586Sdim Self.BuildBasePathArray(Paths, BasePath); 1299226586Sdim Kind = CK_BaseToDerived; 1300226586Sdim return TC_Success; 1301226586Sdim} 1302226586Sdim 1303226586Sdim/// TryStaticMemberPointerUpcast - Tests whether a conversion according to 1304226586Sdim/// C++ 5.2.9p9 is valid: 1305226586Sdim/// 1306226586Sdim/// An rvalue of type "pointer to member of D of type cv1 T" can be 1307226586Sdim/// converted to an rvalue of type "pointer to member of B of type cv2 T", 1308226586Sdim/// where B is a base class of D [...]. 1309226586Sdim/// 1310226586SdimTryCastResult 1311226586SdimTryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType, 1312226586Sdim QualType DestType, bool CStyle, 1313226586Sdim const SourceRange &OpRange, 1314226586Sdim unsigned &msg, CastKind &Kind, 1315226586Sdim CXXCastPath &BasePath) { 1316226586Sdim const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>(); 1317226586Sdim if (!DestMemPtr) 1318226586Sdim return TC_NotApplicable; 1319226586Sdim 1320226586Sdim bool WasOverloadedFunction = false; 1321226586Sdim DeclAccessPair FoundOverload; 1322226586Sdim if (SrcExpr.get()->getType() == Self.Context.OverloadTy) { 1323226586Sdim if (FunctionDecl *Fn 1324226586Sdim = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), DestType, false, 1325226586Sdim FoundOverload)) { 1326226586Sdim CXXMethodDecl *M = cast<CXXMethodDecl>(Fn); 1327226586Sdim SrcType = Self.Context.getMemberPointerType(Fn->getType(), 1328226586Sdim Self.Context.getTypeDeclType(M->getParent()).getTypePtr()); 1329226586Sdim WasOverloadedFunction = true; 1330226586Sdim } 1331226586Sdim } 1332226586Sdim 1333226586Sdim const MemberPointerType *SrcMemPtr = SrcType->getAs<MemberPointerType>(); 1334226586Sdim if (!SrcMemPtr) { 1335226586Sdim msg = diag::err_bad_static_cast_member_pointer_nonmp; 1336226586Sdim return TC_NotApplicable; 1337226586Sdim } 1338226586Sdim 1339226586Sdim // T == T, modulo cv 1340226586Sdim if (!Self.Context.hasSameUnqualifiedType(SrcMemPtr->getPointeeType(), 1341226586Sdim DestMemPtr->getPointeeType())) 1342226586Sdim return TC_NotApplicable; 1343226586Sdim 1344226586Sdim // B base of D 1345226586Sdim QualType SrcClass(SrcMemPtr->getClass(), 0); 1346226586Sdim QualType DestClass(DestMemPtr->getClass(), 0); 1347226586Sdim CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 1348226586Sdim /*DetectVirtual=*/true); 1349226586Sdim if (!Self.IsDerivedFrom(SrcClass, DestClass, Paths)) { 1350226586Sdim return TC_NotApplicable; 1351226586Sdim } 1352226586Sdim 1353226586Sdim // B is a base of D. But is it an allowed base? If not, it's a hard error. 1354226586Sdim if (Paths.isAmbiguous(Self.Context.getCanonicalType(DestClass))) { 1355226586Sdim Paths.clear(); 1356226586Sdim Paths.setRecordingPaths(true); 1357226586Sdim bool StillOkay = Self.IsDerivedFrom(SrcClass, DestClass, Paths); 1358226586Sdim assert(StillOkay); 1359226586Sdim (void)StillOkay; 1360226586Sdim std::string PathDisplayStr = Self.getAmbiguousPathsDisplayString(Paths); 1361226586Sdim Self.Diag(OpRange.getBegin(), diag::err_ambiguous_memptr_conv) 1362226586Sdim << 1 << SrcClass << DestClass << PathDisplayStr << OpRange; 1363226586Sdim msg = 0; 1364226586Sdim return TC_Failed; 1365226586Sdim } 1366226586Sdim 1367226586Sdim if (const RecordType *VBase = Paths.getDetectedVirtual()) { 1368226586Sdim Self.Diag(OpRange.getBegin(), diag::err_memptr_conv_via_virtual) 1369226586Sdim << SrcClass << DestClass << QualType(VBase, 0) << OpRange; 1370226586Sdim msg = 0; 1371226586Sdim return TC_Failed; 1372226586Sdim } 1373226586Sdim 1374226586Sdim if (!CStyle) { 1375226586Sdim switch (Self.CheckBaseClassAccess(OpRange.getBegin(), 1376226586Sdim DestClass, SrcClass, 1377226586Sdim Paths.front(), 1378226586Sdim diag::err_upcast_to_inaccessible_base)) { 1379226586Sdim case Sema::AR_accessible: 1380226586Sdim case Sema::AR_delayed: 1381226586Sdim case Sema::AR_dependent: 1382226586Sdim // Optimistically assume that the delayed and dependent cases 1383226586Sdim // will work out. 1384226586Sdim break; 1385226586Sdim 1386226586Sdim case Sema::AR_inaccessible: 1387226586Sdim msg = 0; 1388226586Sdim return TC_Failed; 1389226586Sdim } 1390226586Sdim } 1391226586Sdim 1392226586Sdim if (WasOverloadedFunction) { 1393226586Sdim // Resolve the address of the overloaded function again, this time 1394226586Sdim // allowing complaints if something goes wrong. 1395226586Sdim FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), 1396226586Sdim DestType, 1397226586Sdim true, 1398226586Sdim FoundOverload); 1399226586Sdim if (!Fn) { 1400226586Sdim msg = 0; 1401226586Sdim return TC_Failed; 1402226586Sdim } 1403226586Sdim 1404226586Sdim SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn); 1405226586Sdim if (!SrcExpr.isUsable()) { 1406226586Sdim msg = 0; 1407226586Sdim return TC_Failed; 1408226586Sdim } 1409226586Sdim } 1410226586Sdim 1411226586Sdim Self.BuildBasePathArray(Paths, BasePath); 1412226586Sdim Kind = CK_DerivedToBaseMemberPointer; 1413226586Sdim return TC_Success; 1414226586Sdim} 1415226586Sdim 1416226586Sdim/// TryStaticImplicitCast - Tests whether a conversion according to C++ 5.2.9p2 1417226586Sdim/// is valid: 1418226586Sdim/// 1419226586Sdim/// An expression e can be explicitly converted to a type T using a 1420226586Sdim/// @c static_cast if the declaration "T t(e);" is well-formed [...]. 1421226586SdimTryCastResult 1422226586SdimTryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, 1423226586Sdim Sema::CheckedConversionKind CCK, 1424226586Sdim const SourceRange &OpRange, unsigned &msg, 1425234353Sdim CastKind &Kind, bool ListInitialization) { 1426226586Sdim if (DestType->isRecordType()) { 1427226586Sdim if (Self.RequireCompleteType(OpRange.getBegin(), DestType, 1428239462Sdim diag::err_bad_dynamic_cast_incomplete) || 1429239462Sdim Self.RequireNonAbstractType(OpRange.getBegin(), DestType, 1430239462Sdim diag::err_allocation_of_abstract_type)) { 1431226586Sdim msg = 0; 1432226586Sdim return TC_Failed; 1433226586Sdim } 1434226586Sdim } 1435234353Sdim 1436226586Sdim InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType); 1437226586Sdim InitializationKind InitKind 1438226586Sdim = (CCK == Sema::CCK_CStyleCast) 1439234353Sdim ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange, 1440234353Sdim ListInitialization) 1441226586Sdim : (CCK == Sema::CCK_FunctionalCast) 1442234353Sdim ? InitializationKind::CreateFunctionalCast(OpRange, ListInitialization) 1443226586Sdim : InitializationKind::CreateCast(OpRange); 1444226586Sdim Expr *SrcExprRaw = SrcExpr.get(); 1445251662Sdim InitializationSequence InitSeq(Self, Entity, InitKind, SrcExprRaw); 1446226586Sdim 1447226586Sdim // At this point of CheckStaticCast, if the destination is a reference, 1448226586Sdim // or the expression is an overload expression this has to work. 1449226586Sdim // There is no other way that works. 1450226586Sdim // On the other hand, if we're checking a C-style cast, we've still got 1451226586Sdim // the reinterpret_cast way. 1452226586Sdim bool CStyle 1453226586Sdim = (CCK == Sema::CCK_CStyleCast || CCK == Sema::CCK_FunctionalCast); 1454226586Sdim if (InitSeq.Failed() && (CStyle || !DestType->isReferenceType())) 1455226586Sdim return TC_NotApplicable; 1456226586Sdim 1457243830Sdim ExprResult Result = InitSeq.Perform(Self, Entity, InitKind, SrcExprRaw); 1458226586Sdim if (Result.isInvalid()) { 1459226586Sdim msg = 0; 1460226586Sdim return TC_Failed; 1461226586Sdim } 1462226586Sdim 1463226586Sdim if (InitSeq.isConstructorInitialization()) 1464226586Sdim Kind = CK_ConstructorConversion; 1465226586Sdim else 1466226586Sdim Kind = CK_NoOp; 1467226586Sdim 1468243830Sdim SrcExpr = Result; 1469226586Sdim return TC_Success; 1470226586Sdim} 1471226586Sdim 1472226586Sdim/// TryConstCast - See if a const_cast from source to destination is allowed, 1473226586Sdim/// and perform it if it is. 1474263508Sdimstatic TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr, 1475263508Sdim QualType DestType, bool CStyle, 1476263508Sdim unsigned &msg) { 1477226586Sdim DestType = Self.Context.getCanonicalType(DestType); 1478263508Sdim QualType SrcType = SrcExpr.get()->getType(); 1479263508Sdim bool NeedToMaterializeTemporary = false; 1480263508Sdim 1481226586Sdim if (const ReferenceType *DestTypeTmp =DestType->getAs<ReferenceType>()) { 1482263508Sdim // C++11 5.2.11p4: 1483263508Sdim // if a pointer to T1 can be explicitly converted to the type "pointer to 1484263508Sdim // T2" using a const_cast, then the following conversions can also be 1485263508Sdim // made: 1486263508Sdim // -- an lvalue of type T1 can be explicitly converted to an lvalue of 1487263508Sdim // type T2 using the cast const_cast<T2&>; 1488263508Sdim // -- a glvalue of type T1 can be explicitly converted to an xvalue of 1489263508Sdim // type T2 using the cast const_cast<T2&&>; and 1490263508Sdim // -- if T1 is a class type, a prvalue of type T1 can be explicitly 1491263508Sdim // converted to an xvalue of type T2 using the cast const_cast<T2&&>. 1492263508Sdim 1493263508Sdim if (isa<LValueReferenceType>(DestTypeTmp) && !SrcExpr.get()->isLValue()) { 1494226586Sdim // Cannot const_cast non-lvalue to lvalue reference type. But if this 1495226586Sdim // is C-style, static_cast might find a way, so we simply suggest a 1496226586Sdim // message and tell the parent to keep searching. 1497226586Sdim msg = diag::err_bad_cxx_cast_rvalue; 1498226586Sdim return TC_NotApplicable; 1499226586Sdim } 1500226586Sdim 1501263508Sdim if (isa<RValueReferenceType>(DestTypeTmp) && SrcExpr.get()->isRValue()) { 1502263508Sdim if (!SrcType->isRecordType()) { 1503263508Sdim // Cannot const_cast non-class prvalue to rvalue reference type. But if 1504263508Sdim // this is C-style, static_cast can do this. 1505263508Sdim msg = diag::err_bad_cxx_cast_rvalue; 1506263508Sdim return TC_NotApplicable; 1507263508Sdim } 1508263508Sdim 1509263508Sdim // Materialize the class prvalue so that the const_cast can bind a 1510263508Sdim // reference to it. 1511263508Sdim NeedToMaterializeTemporary = true; 1512263508Sdim } 1513263508Sdim 1514251662Sdim // It's not completely clear under the standard whether we can 1515251662Sdim // const_cast bit-field gl-values. Doing so would not be 1516251662Sdim // intrinsically complicated, but for now, we say no for 1517251662Sdim // consistency with other compilers and await the word of the 1518251662Sdim // committee. 1519263508Sdim if (SrcExpr.get()->refersToBitField()) { 1520251662Sdim msg = diag::err_bad_cxx_cast_bitfield; 1521251662Sdim return TC_NotApplicable; 1522251662Sdim } 1523251662Sdim 1524226586Sdim DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType()); 1525226586Sdim SrcType = Self.Context.getPointerType(SrcType); 1526226586Sdim } 1527226586Sdim 1528226586Sdim // C++ 5.2.11p5: For a const_cast involving pointers to data members [...] 1529226586Sdim // the rules for const_cast are the same as those used for pointers. 1530226586Sdim 1531226586Sdim if (!DestType->isPointerType() && 1532226586Sdim !DestType->isMemberPointerType() && 1533226586Sdim !DestType->isObjCObjectPointerType()) { 1534226586Sdim // Cannot cast to non-pointer, non-reference type. Note that, if DestType 1535226586Sdim // was a reference type, we converted it to a pointer above. 1536226586Sdim // The status of rvalue references isn't entirely clear, but it looks like 1537226586Sdim // conversion to them is simply invalid. 1538226586Sdim // C++ 5.2.11p3: For two pointer types [...] 1539226586Sdim if (!CStyle) 1540226586Sdim msg = diag::err_bad_const_cast_dest; 1541226586Sdim return TC_NotApplicable; 1542226586Sdim } 1543226586Sdim if (DestType->isFunctionPointerType() || 1544226586Sdim DestType->isMemberFunctionPointerType()) { 1545226586Sdim // Cannot cast direct function pointers. 1546226586Sdim // C++ 5.2.11p2: [...] where T is any object type or the void type [...] 1547226586Sdim // T is the ultimate pointee of source and target type. 1548226586Sdim if (!CStyle) 1549226586Sdim msg = diag::err_bad_const_cast_dest; 1550226586Sdim return TC_NotApplicable; 1551226586Sdim } 1552226586Sdim SrcType = Self.Context.getCanonicalType(SrcType); 1553226586Sdim 1554226586Sdim // Unwrap the pointers. Ignore qualifiers. Terminate early if the types are 1555226586Sdim // completely equal. 1556226586Sdim // C++ 5.2.11p3 describes the core semantics of const_cast. All cv specifiers 1557226586Sdim // in multi-level pointers may change, but the level count must be the same, 1558226586Sdim // as must be the final pointee type. 1559226586Sdim while (SrcType != DestType && 1560226586Sdim Self.Context.UnwrapSimilarPointerTypes(SrcType, DestType)) { 1561226586Sdim Qualifiers SrcQuals, DestQuals; 1562226586Sdim SrcType = Self.Context.getUnqualifiedArrayType(SrcType, SrcQuals); 1563226586Sdim DestType = Self.Context.getUnqualifiedArrayType(DestType, DestQuals); 1564226586Sdim 1565226586Sdim // const_cast is permitted to strip cvr-qualifiers, only. Make sure that 1566226586Sdim // the other qualifiers (e.g., address spaces) are identical. 1567226586Sdim SrcQuals.removeCVRQualifiers(); 1568226586Sdim DestQuals.removeCVRQualifiers(); 1569226586Sdim if (SrcQuals != DestQuals) 1570226586Sdim return TC_NotApplicable; 1571226586Sdim } 1572226586Sdim 1573226586Sdim // Since we're dealing in canonical types, the remainder must be the same. 1574226586Sdim if (SrcType != DestType) 1575226586Sdim return TC_NotApplicable; 1576226586Sdim 1577263508Sdim if (NeedToMaterializeTemporary) 1578263508Sdim // This is a const_cast from a class prvalue to an rvalue reference type. 1579263508Sdim // Materialize a temporary to store the result of the conversion. 1580263508Sdim SrcExpr = new (Self.Context) MaterializeTemporaryExpr( 1581263508Sdim SrcType, SrcExpr.take(), /*IsLValueReference*/ false, 1582263508Sdim /*ExtendingDecl*/ 0); 1583263508Sdim 1584226586Sdim return TC_Success; 1585226586Sdim} 1586226586Sdim 1587226586Sdim// Checks for undefined behavior in reinterpret_cast. 1588226586Sdim// The cases that is checked for is: 1589226586Sdim// *reinterpret_cast<T*>(&a) 1590226586Sdim// reinterpret_cast<T&>(a) 1591226586Sdim// where accessing 'a' as type 'T' will result in undefined behavior. 1592226586Sdimvoid Sema::CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, 1593226586Sdim bool IsDereference, 1594226586Sdim SourceRange Range) { 1595226586Sdim unsigned DiagID = IsDereference ? 1596226586Sdim diag::warn_pointer_indirection_from_incompatible_type : 1597226586Sdim diag::warn_undefined_reinterpret_cast; 1598226586Sdim 1599226586Sdim if (Diags.getDiagnosticLevel(DiagID, Range.getBegin()) == 1600226586Sdim DiagnosticsEngine::Ignored) { 1601226586Sdim return; 1602226586Sdim } 1603226586Sdim 1604226586Sdim QualType SrcTy, DestTy; 1605226586Sdim if (IsDereference) { 1606226586Sdim if (!SrcType->getAs<PointerType>() || !DestType->getAs<PointerType>()) { 1607226586Sdim return; 1608226586Sdim } 1609226586Sdim SrcTy = SrcType->getPointeeType(); 1610226586Sdim DestTy = DestType->getPointeeType(); 1611226586Sdim } else { 1612226586Sdim if (!DestType->getAs<ReferenceType>()) { 1613226586Sdim return; 1614226586Sdim } 1615226586Sdim SrcTy = SrcType; 1616226586Sdim DestTy = DestType->getPointeeType(); 1617226586Sdim } 1618226586Sdim 1619226586Sdim // Cast is compatible if the types are the same. 1620226586Sdim if (Context.hasSameUnqualifiedType(DestTy, SrcTy)) { 1621226586Sdim return; 1622226586Sdim } 1623226586Sdim // or one of the types is a char or void type 1624226586Sdim if (DestTy->isAnyCharacterType() || DestTy->isVoidType() || 1625226586Sdim SrcTy->isAnyCharacterType() || SrcTy->isVoidType()) { 1626226586Sdim return; 1627226586Sdim } 1628226586Sdim // or one of the types is a tag type. 1629226586Sdim if (SrcTy->getAs<TagType>() || DestTy->getAs<TagType>()) { 1630226586Sdim return; 1631226586Sdim } 1632226586Sdim 1633226586Sdim // FIXME: Scoped enums? 1634226586Sdim if ((SrcTy->isUnsignedIntegerType() && DestTy->isSignedIntegerType()) || 1635226586Sdim (SrcTy->isSignedIntegerType() && DestTy->isUnsignedIntegerType())) { 1636226586Sdim if (Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy)) { 1637226586Sdim return; 1638226586Sdim } 1639226586Sdim } 1640226586Sdim 1641226586Sdim Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range; 1642226586Sdim} 1643226586Sdim 1644239462Sdimstatic void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr, 1645239462Sdim QualType DestType) { 1646239462Sdim QualType SrcType = SrcExpr.get()->getType(); 1647249423Sdim if (Self.Context.hasSameType(SrcType, DestType)) 1648249423Sdim return; 1649239462Sdim if (const PointerType *SrcPtrTy = SrcType->getAs<PointerType>()) 1650239462Sdim if (SrcPtrTy->isObjCSelType()) { 1651239462Sdim QualType DT = DestType; 1652239462Sdim if (isa<PointerType>(DestType)) 1653239462Sdim DT = DestType->getPointeeType(); 1654239462Sdim if (!DT.getUnqualifiedType()->isVoidType()) 1655239462Sdim Self.Diag(SrcExpr.get()->getExprLoc(), 1656239462Sdim diag::warn_cast_pointer_from_sel) 1657239462Sdim << SrcType << DestType << SrcExpr.get()->getSourceRange(); 1658239462Sdim } 1659239462Sdim} 1660239462Sdim 1661243830Sdimstatic void checkIntToPointerCast(bool CStyle, SourceLocation Loc, 1662243830Sdim const Expr *SrcExpr, QualType DestType, 1663243830Sdim Sema &Self) { 1664243830Sdim QualType SrcType = SrcExpr->getType(); 1665243830Sdim 1666243830Sdim // Not warning on reinterpret_cast, boolean, constant expressions, etc 1667243830Sdim // are not explicit design choices, but consistent with GCC's behavior. 1668243830Sdim // Feel free to modify them if you've reason/evidence for an alternative. 1669243830Sdim if (CStyle && SrcType->isIntegralType(Self.Context) 1670243830Sdim && !SrcType->isBooleanType() 1671243830Sdim && !SrcType->isEnumeralType() 1672243830Sdim && !SrcExpr->isIntegerConstantExpr(Self.Context) 1673263508Sdim && Self.Context.getTypeSize(DestType) > 1674263508Sdim Self.Context.getTypeSize(SrcType)) { 1675263508Sdim // Separate between casts to void* and non-void* pointers. 1676263508Sdim // Some APIs use (abuse) void* for something like a user context, 1677263508Sdim // and often that value is an integer even if it isn't a pointer itself. 1678263508Sdim // Having a separate warning flag allows users to control the warning 1679263508Sdim // for their workflow. 1680263508Sdim unsigned Diag = DestType->isVoidPointerType() ? 1681263508Sdim diag::warn_int_to_void_pointer_cast 1682263508Sdim : diag::warn_int_to_pointer_cast; 1683263508Sdim Self.Diag(Loc, Diag) << SrcType << DestType; 1684263508Sdim } 1685243830Sdim} 1686243830Sdim 1687226586Sdimstatic TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, 1688226586Sdim QualType DestType, bool CStyle, 1689226586Sdim const SourceRange &OpRange, 1690226586Sdim unsigned &msg, 1691226586Sdim CastKind &Kind) { 1692226586Sdim bool IsLValueCast = false; 1693226586Sdim 1694226586Sdim DestType = Self.Context.getCanonicalType(DestType); 1695226586Sdim QualType SrcType = SrcExpr.get()->getType(); 1696226586Sdim 1697226586Sdim // Is the source an overloaded name? (i.e. &foo) 1698226586Sdim // If so, reinterpret_cast can not help us here (13.4, p1, bullet 5) ... 1699226586Sdim if (SrcType == Self.Context.OverloadTy) { 1700226586Sdim // ... unless foo<int> resolves to an lvalue unambiguously. 1701226586Sdim // TODO: what if this fails because of DiagnoseUseOfDecl or something 1702226586Sdim // like it? 1703226586Sdim ExprResult SingleFunctionExpr = SrcExpr; 1704226586Sdim if (Self.ResolveAndFixSingleFunctionTemplateSpecialization( 1705226586Sdim SingleFunctionExpr, 1706226586Sdim Expr::getValueKindForType(DestType) == VK_RValue // Convert Fun to Ptr 1707226586Sdim ) && SingleFunctionExpr.isUsable()) { 1708243830Sdim SrcExpr = SingleFunctionExpr; 1709226586Sdim SrcType = SrcExpr.get()->getType(); 1710226586Sdim } else { 1711226586Sdim return TC_NotApplicable; 1712226586Sdim } 1713226586Sdim } 1714226586Sdim 1715226586Sdim if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) { 1716239462Sdim if (!SrcExpr.get()->isGLValue()) { 1717239462Sdim // Cannot cast non-glvalue to (lvalue or rvalue) reference type. See the 1718239462Sdim // similar comment in const_cast. 1719226586Sdim msg = diag::err_bad_cxx_cast_rvalue; 1720226586Sdim return TC_NotApplicable; 1721226586Sdim } 1722226586Sdim 1723226586Sdim if (!CStyle) { 1724226586Sdim Self.CheckCompatibleReinterpretCast(SrcType, DestType, 1725226586Sdim /*isDereference=*/false, OpRange); 1726226586Sdim } 1727226586Sdim 1728226586Sdim // C++ 5.2.10p10: [...] a reference cast reinterpret_cast<T&>(x) has the 1729226586Sdim // same effect as the conversion *reinterpret_cast<T*>(&x) with the 1730226586Sdim // built-in & and * operators. 1731226586Sdim 1732226586Sdim const char *inappropriate = 0; 1733226586Sdim switch (SrcExpr.get()->getObjectKind()) { 1734226586Sdim case OK_Ordinary: 1735226586Sdim break; 1736226586Sdim case OK_BitField: inappropriate = "bit-field"; break; 1737226586Sdim case OK_VectorComponent: inappropriate = "vector element"; break; 1738226586Sdim case OK_ObjCProperty: inappropriate = "property expression"; break; 1739234353Sdim case OK_ObjCSubscript: inappropriate = "container subscripting expression"; 1740234353Sdim break; 1741226586Sdim } 1742226586Sdim if (inappropriate) { 1743226586Sdim Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_reference) 1744226586Sdim << inappropriate << DestType 1745226586Sdim << OpRange << SrcExpr.get()->getSourceRange(); 1746226586Sdim msg = 0; SrcExpr = ExprError(); 1747226586Sdim return TC_NotApplicable; 1748226586Sdim } 1749226586Sdim 1750226586Sdim // This code does this transformation for the checked types. 1751226586Sdim DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType()); 1752226586Sdim SrcType = Self.Context.getPointerType(SrcType); 1753226586Sdim 1754226586Sdim IsLValueCast = true; 1755226586Sdim } 1756226586Sdim 1757226586Sdim // Canonicalize source for comparison. 1758226586Sdim SrcType = Self.Context.getCanonicalType(SrcType); 1759226586Sdim 1760226586Sdim const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>(), 1761226586Sdim *SrcMemPtr = SrcType->getAs<MemberPointerType>(); 1762226586Sdim if (DestMemPtr && SrcMemPtr) { 1763226586Sdim // C++ 5.2.10p9: An rvalue of type "pointer to member of X of type T1" 1764226586Sdim // can be explicitly converted to an rvalue of type "pointer to member 1765226586Sdim // of Y of type T2" if T1 and T2 are both function types or both object 1766226586Sdim // types. 1767226586Sdim if (DestMemPtr->getPointeeType()->isFunctionType() != 1768226586Sdim SrcMemPtr->getPointeeType()->isFunctionType()) 1769226586Sdim return TC_NotApplicable; 1770226586Sdim 1771226586Sdim // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away 1772226586Sdim // constness. 1773226586Sdim // A reinterpret_cast followed by a const_cast can, though, so in C-style, 1774226586Sdim // we accept it. 1775226586Sdim if (CastsAwayConstness(Self, SrcType, DestType, /*CheckCVR=*/!CStyle, 1776226586Sdim /*CheckObjCLifetime=*/CStyle)) { 1777226586Sdim msg = diag::err_bad_cxx_cast_qualifiers_away; 1778226586Sdim return TC_Failed; 1779226586Sdim } 1780226586Sdim 1781226586Sdim // Don't allow casting between member pointers of different sizes. 1782226586Sdim if (Self.Context.getTypeSize(DestMemPtr) != 1783226586Sdim Self.Context.getTypeSize(SrcMemPtr)) { 1784226586Sdim msg = diag::err_bad_cxx_cast_member_pointer_size; 1785226586Sdim return TC_Failed; 1786226586Sdim } 1787226586Sdim 1788226586Sdim // A valid member pointer cast. 1789234353Sdim assert(!IsLValueCast); 1790234353Sdim Kind = CK_ReinterpretMemberPointer; 1791226586Sdim return TC_Success; 1792226586Sdim } 1793226586Sdim 1794226586Sdim // See below for the enumeral issue. 1795226586Sdim if (SrcType->isNullPtrType() && DestType->isIntegralType(Self.Context)) { 1796226586Sdim // C++0x 5.2.10p4: A pointer can be explicitly converted to any integral 1797226586Sdim // type large enough to hold it. A value of std::nullptr_t can be 1798226586Sdim // converted to an integral type; the conversion has the same meaning 1799226586Sdim // and validity as a conversion of (void*)0 to the integral type. 1800226586Sdim if (Self.Context.getTypeSize(SrcType) > 1801226586Sdim Self.Context.getTypeSize(DestType)) { 1802226586Sdim msg = diag::err_bad_reinterpret_cast_small_int; 1803226586Sdim return TC_Failed; 1804226586Sdim } 1805226586Sdim Kind = CK_PointerToIntegral; 1806226586Sdim return TC_Success; 1807226586Sdim } 1808226586Sdim 1809226586Sdim bool destIsVector = DestType->isVectorType(); 1810226586Sdim bool srcIsVector = SrcType->isVectorType(); 1811226586Sdim if (srcIsVector || destIsVector) { 1812226586Sdim // FIXME: Should this also apply to floating point types? 1813226586Sdim bool srcIsScalar = SrcType->isIntegralType(Self.Context); 1814226586Sdim bool destIsScalar = DestType->isIntegralType(Self.Context); 1815226586Sdim 1816226586Sdim // Check if this is a cast between a vector and something else. 1817226586Sdim if (!(srcIsScalar && destIsVector) && !(srcIsVector && destIsScalar) && 1818226586Sdim !(srcIsVector && destIsVector)) 1819226586Sdim return TC_NotApplicable; 1820226586Sdim 1821226586Sdim // If both types have the same size, we can successfully cast. 1822226586Sdim if (Self.Context.getTypeSize(SrcType) 1823226586Sdim == Self.Context.getTypeSize(DestType)) { 1824226586Sdim Kind = CK_BitCast; 1825226586Sdim return TC_Success; 1826226586Sdim } 1827226586Sdim 1828226586Sdim if (destIsScalar) 1829226586Sdim msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size; 1830226586Sdim else if (srcIsScalar) 1831226586Sdim msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size; 1832226586Sdim else 1833226586Sdim msg = diag::err_bad_cxx_cast_vector_to_vector_different_size; 1834226586Sdim 1835226586Sdim return TC_Failed; 1836226586Sdim } 1837234353Sdim 1838234353Sdim if (SrcType == DestType) { 1839234353Sdim // C++ 5.2.10p2 has a note that mentions that, subject to all other 1840234353Sdim // restrictions, a cast to the same type is allowed so long as it does not 1841234353Sdim // cast away constness. In C++98, the intent was not entirely clear here, 1842234353Sdim // since all other paragraphs explicitly forbid casts to the same type. 1843234353Sdim // C++11 clarifies this case with p2. 1844234353Sdim // 1845234353Sdim // The only allowed types are: integral, enumeration, pointer, or 1846234353Sdim // pointer-to-member types. We also won't restrict Obj-C pointers either. 1847234353Sdim Kind = CK_NoOp; 1848234353Sdim TryCastResult Result = TC_NotApplicable; 1849234353Sdim if (SrcType->isIntegralOrEnumerationType() || 1850234353Sdim SrcType->isAnyPointerType() || 1851234353Sdim SrcType->isMemberPointerType() || 1852234353Sdim SrcType->isBlockPointerType()) { 1853234353Sdim Result = TC_Success; 1854234353Sdim } 1855234353Sdim return Result; 1856234353Sdim } 1857234353Sdim 1858226586Sdim bool destIsPtr = DestType->isAnyPointerType() || 1859226586Sdim DestType->isBlockPointerType(); 1860226586Sdim bool srcIsPtr = SrcType->isAnyPointerType() || 1861226586Sdim SrcType->isBlockPointerType(); 1862226586Sdim if (!destIsPtr && !srcIsPtr) { 1863226586Sdim // Except for std::nullptr_t->integer and lvalue->reference, which are 1864226586Sdim // handled above, at least one of the two arguments must be a pointer. 1865226586Sdim return TC_NotApplicable; 1866226586Sdim } 1867226586Sdim 1868226586Sdim if (DestType->isIntegralType(Self.Context)) { 1869226586Sdim assert(srcIsPtr && "One type must be a pointer"); 1870226586Sdim // C++ 5.2.10p4: A pointer can be explicitly converted to any integral 1871226586Sdim // type large enough to hold it; except in Microsoft mode, where the 1872263508Sdim // integral type size doesn't matter (except we don't allow bool). 1873263508Sdim bool MicrosoftException = Self.getLangOpts().MicrosoftExt && 1874263508Sdim !DestType->isBooleanType(); 1875226586Sdim if ((Self.Context.getTypeSize(SrcType) > 1876226586Sdim Self.Context.getTypeSize(DestType)) && 1877263508Sdim !MicrosoftException) { 1878226586Sdim msg = diag::err_bad_reinterpret_cast_small_int; 1879226586Sdim return TC_Failed; 1880226586Sdim } 1881226586Sdim Kind = CK_PointerToIntegral; 1882226586Sdim return TC_Success; 1883226586Sdim } 1884226586Sdim 1885226586Sdim if (SrcType->isIntegralOrEnumerationType()) { 1886226586Sdim assert(destIsPtr && "One type must be a pointer"); 1887243830Sdim checkIntToPointerCast(CStyle, OpRange.getBegin(), SrcExpr.get(), DestType, 1888243830Sdim Self); 1889226586Sdim // C++ 5.2.10p5: A value of integral or enumeration type can be explicitly 1890226586Sdim // converted to a pointer. 1891226586Sdim // C++ 5.2.10p9: [Note: ...a null pointer constant of integral type is not 1892226586Sdim // necessarily converted to a null pointer value.] 1893226586Sdim Kind = CK_IntegralToPointer; 1894226586Sdim return TC_Success; 1895226586Sdim } 1896226586Sdim 1897226586Sdim if (!destIsPtr || !srcIsPtr) { 1898226586Sdim // With the valid non-pointer conversions out of the way, we can be even 1899226586Sdim // more stringent. 1900226586Sdim return TC_NotApplicable; 1901226586Sdim } 1902226586Sdim 1903226586Sdim // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away constness. 1904226586Sdim // The C-style cast operator can. 1905226586Sdim if (CastsAwayConstness(Self, SrcType, DestType, /*CheckCVR=*/!CStyle, 1906226586Sdim /*CheckObjCLifetime=*/CStyle)) { 1907226586Sdim msg = diag::err_bad_cxx_cast_qualifiers_away; 1908226586Sdim return TC_Failed; 1909226586Sdim } 1910226586Sdim 1911226586Sdim // Cannot convert between block pointers and Objective-C object pointers. 1912226586Sdim if ((SrcType->isBlockPointerType() && DestType->isObjCObjectPointerType()) || 1913226586Sdim (DestType->isBlockPointerType() && SrcType->isObjCObjectPointerType())) 1914226586Sdim return TC_NotApplicable; 1915226586Sdim 1916226586Sdim if (IsLValueCast) { 1917226586Sdim Kind = CK_LValueBitCast; 1918226586Sdim } else if (DestType->isObjCObjectPointerType()) { 1919226586Sdim Kind = Self.PrepareCastToObjCObjectPointer(SrcExpr); 1920226586Sdim } else if (DestType->isBlockPointerType()) { 1921226586Sdim if (!SrcType->isBlockPointerType()) { 1922226586Sdim Kind = CK_AnyPointerToBlockPointerCast; 1923226586Sdim } else { 1924226586Sdim Kind = CK_BitCast; 1925226586Sdim } 1926226586Sdim } else { 1927226586Sdim Kind = CK_BitCast; 1928226586Sdim } 1929226586Sdim 1930226586Sdim // Any pointer can be cast to an Objective-C pointer type with a C-style 1931226586Sdim // cast. 1932226586Sdim if (CStyle && DestType->isObjCObjectPointerType()) { 1933226586Sdim return TC_Success; 1934226586Sdim } 1935239462Sdim if (CStyle) 1936239462Sdim DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType); 1937239462Sdim 1938226586Sdim // Not casting away constness, so the only remaining check is for compatible 1939226586Sdim // pointer categories. 1940226586Sdim 1941226586Sdim if (SrcType->isFunctionPointerType()) { 1942226586Sdim if (DestType->isFunctionPointerType()) { 1943226586Sdim // C++ 5.2.10p6: A pointer to a function can be explicitly converted to 1944226586Sdim // a pointer to a function of a different type. 1945226586Sdim return TC_Success; 1946226586Sdim } 1947226586Sdim 1948226586Sdim // C++0x 5.2.10p8: Converting a pointer to a function into a pointer to 1949226586Sdim // an object type or vice versa is conditionally-supported. 1950226586Sdim // Compilers support it in C++03 too, though, because it's necessary for 1951226586Sdim // casting the return value of dlsym() and GetProcAddress(). 1952226586Sdim // FIXME: Conditionally-supported behavior should be configurable in the 1953226586Sdim // TargetInfo or similar. 1954234353Sdim Self.Diag(OpRange.getBegin(), 1955249423Sdim Self.getLangOpts().CPlusPlus11 ? 1956234353Sdim diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj) 1957234353Sdim << OpRange; 1958226586Sdim return TC_Success; 1959226586Sdim } 1960226586Sdim 1961226586Sdim if (DestType->isFunctionPointerType()) { 1962226586Sdim // See above. 1963234353Sdim Self.Diag(OpRange.getBegin(), 1964249423Sdim Self.getLangOpts().CPlusPlus11 ? 1965234353Sdim diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj) 1966234353Sdim << OpRange; 1967226586Sdim return TC_Success; 1968226586Sdim } 1969226586Sdim 1970226586Sdim // C++ 5.2.10p7: A pointer to an object can be explicitly converted to 1971226586Sdim // a pointer to an object of different type. 1972226586Sdim // Void pointers are not specified, but supported by every compiler out there. 1973226586Sdim // So we finish by allowing everything that remains - it's got to be two 1974226586Sdim // object pointers. 1975226586Sdim return TC_Success; 1976226586Sdim} 1977226586Sdim 1978234353Sdimvoid CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, 1979234353Sdim bool ListInitialization) { 1980226586Sdim // Handle placeholders. 1981226586Sdim if (isPlaceholder()) { 1982226586Sdim // C-style casts can resolve __unknown_any types. 1983226586Sdim if (claimPlaceholder(BuiltinType::UnknownAny)) { 1984226586Sdim SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType, 1985226586Sdim SrcExpr.get(), Kind, 1986226586Sdim ValueKind, BasePath); 1987226586Sdim return; 1988226586Sdim } 1989226586Sdim 1990226586Sdim checkNonOverloadPlaceholders(); 1991226586Sdim if (SrcExpr.isInvalid()) 1992226586Sdim return; 1993234353Sdim } 1994226586Sdim 1995226586Sdim // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". 1996226586Sdim // This test is outside everything else because it's the only case where 1997226586Sdim // a non-lvalue-reference target type does not lead to decay. 1998226586Sdim if (DestType->isVoidType()) { 1999226586Sdim Kind = CK_ToVoid; 2000226586Sdim 2001226586Sdim if (claimPlaceholder(BuiltinType::Overload)) { 2002226586Sdim Self.ResolveAndFixSingleFunctionTemplateSpecialization( 2003226586Sdim SrcExpr, /* Decay Function to ptr */ false, 2004226586Sdim /* Complain */ true, DestRange, DestType, 2005226586Sdim diag::err_bad_cstyle_cast_overload); 2006226586Sdim if (SrcExpr.isInvalid()) 2007226586Sdim return; 2008226586Sdim } 2009226586Sdim 2010226586Sdim SrcExpr = Self.IgnoredValueConversions(SrcExpr.take()); 2011226586Sdim return; 2012226586Sdim } 2013226586Sdim 2014226586Sdim // If the type is dependent, we won't do any other semantic analysis now. 2015263508Sdim if (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() || 2016263508Sdim SrcExpr.get()->isValueDependent()) { 2017226586Sdim assert(Kind == CK_Dependent); 2018226586Sdim return; 2019226586Sdim } 2020226586Sdim 2021226586Sdim if (ValueKind == VK_RValue && !DestType->isRecordType() && 2022226586Sdim !isPlaceholder(BuiltinType::Overload)) { 2023226586Sdim SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); 2024226586Sdim if (SrcExpr.isInvalid()) 2025226586Sdim return; 2026226586Sdim } 2027226586Sdim 2028226586Sdim // AltiVec vector initialization with a single literal. 2029226586Sdim if (const VectorType *vecTy = DestType->getAs<VectorType>()) 2030226586Sdim if (vecTy->getVectorKind() == VectorType::AltiVecVector 2031226586Sdim && (SrcExpr.get()->getType()->isIntegerType() 2032226586Sdim || SrcExpr.get()->getType()->isFloatingType())) { 2033226586Sdim Kind = CK_VectorSplat; 2034226586Sdim return; 2035226586Sdim } 2036226586Sdim 2037226586Sdim // C++ [expr.cast]p5: The conversions performed by 2038226586Sdim // - a const_cast, 2039226586Sdim // - a static_cast, 2040226586Sdim // - a static_cast followed by a const_cast, 2041226586Sdim // - a reinterpret_cast, or 2042226586Sdim // - a reinterpret_cast followed by a const_cast, 2043226586Sdim // can be performed using the cast notation of explicit type conversion. 2044226586Sdim // [...] If a conversion can be interpreted in more than one of the ways 2045226586Sdim // listed above, the interpretation that appears first in the list is used, 2046226586Sdim // even if a cast resulting from that interpretation is ill-formed. 2047226586Sdim // In plain language, this means trying a const_cast ... 2048226586Sdim unsigned msg = diag::err_bad_cxx_cast_generic; 2049263508Sdim TryCastResult tcr = TryConstCast(Self, SrcExpr, DestType, 2050226586Sdim /*CStyle*/true, msg); 2051263508Sdim if (SrcExpr.isInvalid()) 2052263508Sdim return; 2053226586Sdim if (tcr == TC_Success) 2054226586Sdim Kind = CK_NoOp; 2055226586Sdim 2056226586Sdim Sema::CheckedConversionKind CCK 2057226586Sdim = FunctionalStyle? Sema::CCK_FunctionalCast 2058226586Sdim : Sema::CCK_CStyleCast; 2059226586Sdim if (tcr == TC_NotApplicable) { 2060226586Sdim // ... or if that is not possible, a static_cast, ignoring const, ... 2061226586Sdim tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange, 2062234353Sdim msg, Kind, BasePath, ListInitialization); 2063226586Sdim if (SrcExpr.isInvalid()) 2064226586Sdim return; 2065226586Sdim 2066226586Sdim if (tcr == TC_NotApplicable) { 2067226586Sdim // ... and finally a reinterpret_cast, ignoring const. 2068226586Sdim tcr = TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/true, 2069226586Sdim OpRange, msg, Kind); 2070226586Sdim if (SrcExpr.isInvalid()) 2071226586Sdim return; 2072226586Sdim } 2073226586Sdim } 2074226586Sdim 2075234353Sdim if (Self.getLangOpts().ObjCAutoRefCount && tcr == TC_Success) 2076226586Sdim checkObjCARCConversion(CCK); 2077226586Sdim 2078226586Sdim if (tcr != TC_Success && msg != 0) { 2079226586Sdim if (SrcExpr.get()->getType() == Self.Context.OverloadTy) { 2080226586Sdim DeclAccessPair Found; 2081226586Sdim FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), 2082226586Sdim DestType, 2083226586Sdim /*Complain*/ true, 2084226586Sdim Found); 2085226586Sdim 2086226586Sdim assert(!Fn && "cast failed but able to resolve overload expression!!"); 2087226586Sdim (void)Fn; 2088226586Sdim 2089226586Sdim } else { 2090226586Sdim diagnoseBadCast(Self, msg, (FunctionalStyle ? CT_Functional : CT_CStyle), 2091234353Sdim OpRange, SrcExpr.get(), DestType, ListInitialization); 2092226586Sdim } 2093226586Sdim } else if (Kind == CK_BitCast) { 2094226586Sdim checkCastAlign(); 2095226586Sdim } 2096226586Sdim 2097226586Sdim // Clear out SrcExpr if there was a fatal error. 2098226586Sdim if (tcr != TC_Success) 2099226586Sdim SrcExpr = ExprError(); 2100226586Sdim} 2101226586Sdim 2102243830Sdim/// DiagnoseBadFunctionCast - Warn whenever a function call is cast to a 2103243830Sdim/// non-matching type. Such as enum function call to int, int call to 2104243830Sdim/// pointer; etc. Cast to 'void' is an exception. 2105243830Sdimstatic void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr, 2106243830Sdim QualType DestType) { 2107243830Sdim if (Self.Diags.getDiagnosticLevel(diag::warn_bad_function_cast, 2108243830Sdim SrcExpr.get()->getExprLoc()) 2109243830Sdim == DiagnosticsEngine::Ignored) 2110243830Sdim return; 2111243830Sdim 2112243830Sdim if (!isa<CallExpr>(SrcExpr.get())) 2113243830Sdim return; 2114243830Sdim 2115243830Sdim QualType SrcType = SrcExpr.get()->getType(); 2116243830Sdim if (DestType.getUnqualifiedType()->isVoidType()) 2117243830Sdim return; 2118243830Sdim if ((SrcType->isAnyPointerType() || SrcType->isBlockPointerType()) 2119243830Sdim && (DestType->isAnyPointerType() || DestType->isBlockPointerType())) 2120243830Sdim return; 2121243830Sdim if (SrcType->isIntegerType() && DestType->isIntegerType() && 2122243830Sdim (SrcType->isBooleanType() == DestType->isBooleanType()) && 2123243830Sdim (SrcType->isEnumeralType() == DestType->isEnumeralType())) 2124243830Sdim return; 2125243830Sdim if (SrcType->isRealFloatingType() && DestType->isRealFloatingType()) 2126243830Sdim return; 2127243830Sdim if (SrcType->isEnumeralType() && DestType->isEnumeralType()) 2128243830Sdim return; 2129243830Sdim if (SrcType->isComplexType() && DestType->isComplexType()) 2130243830Sdim return; 2131243830Sdim if (SrcType->isComplexIntegerType() && DestType->isComplexIntegerType()) 2132243830Sdim return; 2133243830Sdim 2134243830Sdim Self.Diag(SrcExpr.get()->getExprLoc(), 2135243830Sdim diag::warn_bad_function_cast) 2136243830Sdim << SrcType << DestType << SrcExpr.get()->getSourceRange(); 2137243830Sdim} 2138243830Sdim 2139226586Sdim/// Check the semantics of a C-style cast operation, in C. 2140226586Sdimvoid CastOperation::CheckCStyleCast() { 2141234353Sdim assert(!Self.getLangOpts().CPlusPlus); 2142226586Sdim 2143234353Sdim // C-style casts can resolve __unknown_any types. 2144234353Sdim if (claimPlaceholder(BuiltinType::UnknownAny)) { 2145234353Sdim SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType, 2146234353Sdim SrcExpr.get(), Kind, 2147234353Sdim ValueKind, BasePath); 2148234353Sdim return; 2149234353Sdim } 2150226586Sdim 2151226586Sdim // C99 6.5.4p2: the cast type needs to be void or scalar and the expression 2152226586Sdim // type needs to be scalar. 2153226586Sdim if (DestType->isVoidType()) { 2154226586Sdim // We don't necessarily do lvalue-to-rvalue conversions on this. 2155226586Sdim SrcExpr = Self.IgnoredValueConversions(SrcExpr.take()); 2156226586Sdim if (SrcExpr.isInvalid()) 2157226586Sdim return; 2158226586Sdim 2159226586Sdim // Cast to void allows any expr type. 2160226586Sdim Kind = CK_ToVoid; 2161226586Sdim return; 2162226586Sdim } 2163226586Sdim 2164226586Sdim SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); 2165226586Sdim if (SrcExpr.isInvalid()) 2166226586Sdim return; 2167226586Sdim QualType SrcType = SrcExpr.get()->getType(); 2168226586Sdim 2169234353Sdim assert(!SrcType->isPlaceholderType()); 2170234353Sdim 2171226586Sdim if (Self.RequireCompleteType(OpRange.getBegin(), DestType, 2172226586Sdim diag::err_typecheck_cast_to_incomplete)) { 2173226586Sdim SrcExpr = ExprError(); 2174226586Sdim return; 2175226586Sdim } 2176226586Sdim 2177226586Sdim if (!DestType->isScalarType() && !DestType->isVectorType()) { 2178226586Sdim const RecordType *DestRecordTy = DestType->getAs<RecordType>(); 2179226586Sdim 2180226586Sdim if (DestRecordTy && Self.Context.hasSameUnqualifiedType(DestType, SrcType)){ 2181226586Sdim // GCC struct/union extension: allow cast to self. 2182226586Sdim Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar) 2183226586Sdim << DestType << SrcExpr.get()->getSourceRange(); 2184226586Sdim Kind = CK_NoOp; 2185226586Sdim return; 2186226586Sdim } 2187226586Sdim 2188226586Sdim // GCC's cast to union extension. 2189226586Sdim if (DestRecordTy && DestRecordTy->getDecl()->isUnion()) { 2190226586Sdim RecordDecl *RD = DestRecordTy->getDecl(); 2191226586Sdim RecordDecl::field_iterator Field, FieldEnd; 2192226586Sdim for (Field = RD->field_begin(), FieldEnd = RD->field_end(); 2193226586Sdim Field != FieldEnd; ++Field) { 2194226586Sdim if (Self.Context.hasSameUnqualifiedType(Field->getType(), SrcType) && 2195226586Sdim !Field->isUnnamedBitfield()) { 2196226586Sdim Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union) 2197226586Sdim << SrcExpr.get()->getSourceRange(); 2198226586Sdim break; 2199226586Sdim } 2200226586Sdim } 2201226586Sdim if (Field == FieldEnd) { 2202226586Sdim Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type) 2203226586Sdim << SrcType << SrcExpr.get()->getSourceRange(); 2204226586Sdim SrcExpr = ExprError(); 2205226586Sdim return; 2206226586Sdim } 2207226586Sdim Kind = CK_ToUnion; 2208226586Sdim return; 2209226586Sdim } 2210226586Sdim 2211226586Sdim // Reject any other conversions to non-scalar types. 2212226586Sdim Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar) 2213226586Sdim << DestType << SrcExpr.get()->getSourceRange(); 2214226586Sdim SrcExpr = ExprError(); 2215226586Sdim return; 2216226586Sdim } 2217226586Sdim 2218226586Sdim // The type we're casting to is known to be a scalar or vector. 2219226586Sdim 2220226586Sdim // Require the operand to be a scalar or vector. 2221226586Sdim if (!SrcType->isScalarType() && !SrcType->isVectorType()) { 2222226586Sdim Self.Diag(SrcExpr.get()->getExprLoc(), 2223226586Sdim diag::err_typecheck_expect_scalar_operand) 2224226586Sdim << SrcType << SrcExpr.get()->getSourceRange(); 2225226586Sdim SrcExpr = ExprError(); 2226226586Sdim return; 2227226586Sdim } 2228226586Sdim 2229226586Sdim if (DestType->isExtVectorType()) { 2230226586Sdim SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.take(), Kind); 2231226586Sdim return; 2232226586Sdim } 2233226586Sdim 2234226586Sdim if (const VectorType *DestVecTy = DestType->getAs<VectorType>()) { 2235226586Sdim if (DestVecTy->getVectorKind() == VectorType::AltiVecVector && 2236226586Sdim (SrcType->isIntegerType() || SrcType->isFloatingType())) { 2237226586Sdim Kind = CK_VectorSplat; 2238226586Sdim } else if (Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) { 2239226586Sdim SrcExpr = ExprError(); 2240226586Sdim } 2241226586Sdim return; 2242226586Sdim } 2243226586Sdim 2244226586Sdim if (SrcType->isVectorType()) { 2245226586Sdim if (Self.CheckVectorCast(OpRange, SrcType, DestType, Kind)) 2246226586Sdim SrcExpr = ExprError(); 2247226586Sdim return; 2248226586Sdim } 2249226586Sdim 2250226586Sdim // The source and target types are both scalars, i.e. 2251226586Sdim // - arithmetic types (fundamental, enum, and complex) 2252226586Sdim // - all kinds of pointers 2253226586Sdim // Note that member pointers were filtered out with C++, above. 2254226586Sdim 2255226586Sdim if (isa<ObjCSelectorExpr>(SrcExpr.get())) { 2256226586Sdim Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr); 2257226586Sdim SrcExpr = ExprError(); 2258226586Sdim return; 2259226586Sdim } 2260226586Sdim 2261226586Sdim // If either type is a pointer, the other type has to be either an 2262226586Sdim // integer or a pointer. 2263226586Sdim if (!DestType->isArithmeticType()) { 2264226586Sdim if (!SrcType->isIntegralType(Self.Context) && SrcType->isArithmeticType()) { 2265226586Sdim Self.Diag(SrcExpr.get()->getExprLoc(), 2266226586Sdim diag::err_cast_pointer_from_non_pointer_int) 2267226586Sdim << SrcType << SrcExpr.get()->getSourceRange(); 2268226586Sdim SrcExpr = ExprError(); 2269226586Sdim return; 2270226586Sdim } 2271243830Sdim checkIntToPointerCast(/* CStyle */ true, OpRange.getBegin(), SrcExpr.get(), 2272243830Sdim DestType, Self); 2273226586Sdim } else if (!SrcType->isArithmeticType()) { 2274226586Sdim if (!DestType->isIntegralType(Self.Context) && 2275226586Sdim DestType->isArithmeticType()) { 2276226586Sdim Self.Diag(SrcExpr.get()->getLocStart(), 2277226586Sdim diag::err_cast_pointer_to_non_pointer_int) 2278234353Sdim << DestType << SrcExpr.get()->getSourceRange(); 2279226586Sdim SrcExpr = ExprError(); 2280226586Sdim return; 2281226586Sdim } 2282226586Sdim } 2283226586Sdim 2284249423Sdim if (Self.getLangOpts().OpenCL && !Self.getOpenCLOptions().cl_khr_fp16) { 2285249423Sdim if (DestType->isHalfType()) { 2286249423Sdim Self.Diag(SrcExpr.get()->getLocStart(), diag::err_opencl_cast_to_half) 2287249423Sdim << DestType << SrcExpr.get()->getSourceRange(); 2288249423Sdim SrcExpr = ExprError(); 2289249423Sdim return; 2290249423Sdim } 2291249423Sdim } 2292249423Sdim 2293226586Sdim // ARC imposes extra restrictions on casts. 2294234353Sdim if (Self.getLangOpts().ObjCAutoRefCount) { 2295226586Sdim checkObjCARCConversion(Sema::CCK_CStyleCast); 2296226586Sdim if (SrcExpr.isInvalid()) 2297226586Sdim return; 2298226586Sdim 2299226586Sdim if (const PointerType *CastPtr = DestType->getAs<PointerType>()) { 2300226586Sdim if (const PointerType *ExprPtr = SrcType->getAs<PointerType>()) { 2301226586Sdim Qualifiers CastQuals = CastPtr->getPointeeType().getQualifiers(); 2302226586Sdim Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers(); 2303226586Sdim if (CastPtr->getPointeeType()->isObjCLifetimeType() && 2304226586Sdim ExprPtr->getPointeeType()->isObjCLifetimeType() && 2305226586Sdim !CastQuals.compatiblyIncludesObjCLifetime(ExprQuals)) { 2306226586Sdim Self.Diag(SrcExpr.get()->getLocStart(), 2307226586Sdim diag::err_typecheck_incompatible_ownership) 2308226586Sdim << SrcType << DestType << Sema::AA_Casting 2309226586Sdim << SrcExpr.get()->getSourceRange(); 2310226586Sdim return; 2311226586Sdim } 2312226586Sdim } 2313226586Sdim } 2314226586Sdim else if (!Self.CheckObjCARCUnavailableWeakConversion(DestType, SrcType)) { 2315226586Sdim Self.Diag(SrcExpr.get()->getLocStart(), 2316226586Sdim diag::err_arc_convesion_of_weak_unavailable) 2317226586Sdim << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange(); 2318226586Sdim SrcExpr = ExprError(); 2319226586Sdim return; 2320226586Sdim } 2321226586Sdim } 2322239462Sdim DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType); 2323243830Sdim DiagnoseBadFunctionCast(Self, SrcExpr, DestType); 2324226586Sdim Kind = Self.PrepareScalarCast(SrcExpr, DestType); 2325226586Sdim if (SrcExpr.isInvalid()) 2326226586Sdim return; 2327226586Sdim 2328226586Sdim if (Kind == CK_BitCast) 2329226586Sdim checkCastAlign(); 2330226586Sdim} 2331226586Sdim 2332226586SdimExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc, 2333226586Sdim TypeSourceInfo *CastTypeInfo, 2334226586Sdim SourceLocation RPLoc, 2335226586Sdim Expr *CastExpr) { 2336226586Sdim CastOperation Op(*this, CastTypeInfo->getType(), CastExpr); 2337226586Sdim Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange(); 2338226586Sdim Op.OpRange = SourceRange(LPLoc, CastExpr->getLocEnd()); 2339226586Sdim 2340234353Sdim if (getLangOpts().CPlusPlus) { 2341234353Sdim Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ false, 2342234353Sdim isa<InitListExpr>(CastExpr)); 2343226586Sdim } else { 2344226586Sdim Op.CheckCStyleCast(); 2345226586Sdim } 2346226586Sdim 2347226586Sdim if (Op.SrcExpr.isInvalid()) 2348226586Sdim return ExprError(); 2349226586Sdim 2350234353Sdim return Op.complete(CStyleCastExpr::Create(Context, Op.ResultType, 2351234353Sdim Op.ValueKind, Op.Kind, Op.SrcExpr.take(), 2352234353Sdim &Op.BasePath, CastTypeInfo, LPLoc, RPLoc)); 2353226586Sdim} 2354226586Sdim 2355226586SdimExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo, 2356226586Sdim SourceLocation LPLoc, 2357226586Sdim Expr *CastExpr, 2358226586Sdim SourceLocation RPLoc) { 2359234353Sdim assert(LPLoc.isValid() && "List-initialization shouldn't get here."); 2360226586Sdim CastOperation Op(*this, CastTypeInfo->getType(), CastExpr); 2361226586Sdim Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange(); 2362226586Sdim Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getLocEnd()); 2363226586Sdim 2364234353Sdim Op.CheckCXXCStyleCast(/*FunctionalStyle=*/true, /*ListInit=*/false); 2365226586Sdim if (Op.SrcExpr.isInvalid()) 2366226586Sdim return ExprError(); 2367239462Sdim 2368239462Sdim if (CXXConstructExpr *ConstructExpr = dyn_cast<CXXConstructExpr>(Op.SrcExpr.get())) 2369263508Sdim ConstructExpr->setParenOrBraceRange(SourceRange(LPLoc, RPLoc)); 2370226586Sdim 2371234353Sdim return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType, 2372263508Sdim Op.ValueKind, CastTypeInfo, Op.Kind, 2373263508Sdim Op.SrcExpr.take(), &Op.BasePath, LPLoc, RPLoc)); 2374226586Sdim} 2375