3496 lines · cpp
1//===--- SemaCast.cpp - Semantic Analysis for Casts -----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements semantic analysis for cast expressions, including10// 1) C-style casts like '(int) x'11// 2) C++ functional casts like 'int(x)'12// 3) C++ named casts like 'static_cast<int>(x)'13//14//===----------------------------------------------------------------------===//15 16#include "clang/AST/ASTContext.h"17#include "clang/AST/ASTStructuralEquivalence.h"18#include "clang/AST/CXXInheritance.h"19#include "clang/AST/ExprCXX.h"20#include "clang/AST/ExprObjC.h"21#include "clang/AST/RecordLayout.h"22#include "clang/Basic/PartialDiagnostic.h"23#include "clang/Basic/TargetInfo.h"24#include "clang/Lex/Preprocessor.h"25#include "clang/Sema/Initialization.h"26#include "clang/Sema/SemaHLSL.h"27#include "clang/Sema/SemaObjC.h"28#include "clang/Sema/SemaRISCV.h"29#include "llvm/ADT/SmallVector.h"30#include "llvm/ADT/StringExtras.h"31#include <set>32using namespace clang;33 34 35 36enum TryCastResult {37 TC_NotApplicable, ///< The cast method is not applicable.38 TC_Success, ///< The cast method is appropriate and successful.39 TC_Extension, ///< The cast method is appropriate and accepted as a40 ///< language extension.41 TC_Failed ///< The cast method is appropriate, but failed. A42 ///< diagnostic has been emitted.43};44 45static bool isValidCast(TryCastResult TCR) {46 return TCR == TC_Success || TCR == TC_Extension;47}48 49enum CastType {50 CT_Const, ///< const_cast51 CT_Static, ///< static_cast52 CT_Reinterpret, ///< reinterpret_cast53 CT_Dynamic, ///< dynamic_cast54 CT_CStyle, ///< (Type)expr55 CT_Functional, ///< Type(expr)56 CT_Addrspace ///< addrspace_cast57};58 59namespace {60 struct CastOperation {61 CastOperation(Sema &S, QualType destType, ExprResult src)62 : Self(S), SrcExpr(src), DestType(destType),63 ResultType(destType.getNonLValueExprType(S.Context)),64 ValueKind(Expr::getValueKindForType(destType)),65 Kind(CK_Dependent), IsARCUnbridgedCast(false) {66 67 // C++ [expr.type]/8.2.2:68 // If a pr-value initially has the type cv-T, where T is a69 // cv-unqualified non-class, non-array type, the type of the70 // expression is adjusted to T prior to any further analysis.71 // C23 6.5.4p6:72 // Preceding an expression by a parenthesized type name converts the73 // value of the expression to the unqualified, non-atomic version of74 // the named type.75 // Don't drop __ptrauth qualifiers. We want to treat casting to a76 // __ptrauth-qualified type as an error instead of implicitly ignoring77 // the qualifier.78 if (!S.Context.getLangOpts().ObjC && !DestType->isRecordType() &&79 !DestType->isArrayType() && !DestType.getPointerAuth()) {80 DestType = DestType.getAtomicUnqualifiedType();81 }82 83 if (const BuiltinType *placeholder =84 src.get()->getType()->getAsPlaceholderType()) {85 PlaceholderKind = placeholder->getKind();86 } else {87 PlaceholderKind = (BuiltinType::Kind) 0;88 }89 }90 91 Sema &Self;92 ExprResult SrcExpr;93 QualType DestType;94 QualType ResultType;95 ExprValueKind ValueKind;96 CastKind Kind;97 BuiltinType::Kind PlaceholderKind;98 CXXCastPath BasePath;99 bool IsARCUnbridgedCast;100 101 struct OpRangeType {102 SourceLocation Locations[3];103 104 OpRangeType(SourceLocation Begin, SourceLocation LParen,105 SourceLocation RParen)106 : Locations{Begin, LParen, RParen} {}107 108 OpRangeType() = default;109 110 SourceLocation getBegin() const { return Locations[0]; }111 112 SourceLocation getLParenLoc() const { return Locations[1]; }113 114 SourceLocation getRParenLoc() const { return Locations[2]; }115 116 friend const StreamingDiagnostic &117 operator<<(const StreamingDiagnostic &DB, OpRangeType Op) {118 return DB << SourceRange(Op);119 }120 121 SourceRange getParenRange() const {122 return SourceRange(getLParenLoc(), getRParenLoc());123 }124 125 operator SourceRange() const {126 return SourceRange(getBegin(), getRParenLoc());127 }128 };129 130 OpRangeType OpRange;131 SourceRange DestRange;132 133 // Top-level semantics-checking routines.134 void CheckConstCast();135 void CheckReinterpretCast();136 void CheckStaticCast();137 void CheckDynamicCast();138 void CheckCXXCStyleCast(bool FunctionalCast, bool ListInitialization);139 bool CheckHLSLCStyleCast(CheckedConversionKind CCK);140 void CheckCStyleCast();141 void CheckBuiltinBitCast();142 void CheckAddrspaceCast();143 144 void updatePartOfExplicitCastFlags(CastExpr *CE) {145 // Walk down from the CE to the OrigSrcExpr, and mark all immediate146 // ImplicitCastExpr's as being part of ExplicitCastExpr. The original CE147 // (which is a ExplicitCastExpr), and the OrigSrcExpr are not touched.148 for (; auto *ICE = dyn_cast<ImplicitCastExpr>(CE->getSubExpr()); CE = ICE)149 ICE->setIsPartOfExplicitCast(true);150 }151 152 /// Complete an apparently-successful cast operation that yields153 /// the given expression.154 ExprResult complete(CastExpr *castExpr) {155 // If this is an unbridged cast, wrap the result in an implicit156 // cast that yields the unbridged-cast placeholder type.157 if (IsARCUnbridgedCast) {158 castExpr = ImplicitCastExpr::Create(159 Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent,160 castExpr, nullptr, castExpr->getValueKind(),161 Self.CurFPFeatureOverrides());162 }163 updatePartOfExplicitCastFlags(castExpr);164 return castExpr;165 }166 167 // Internal convenience methods.168 169 /// Try to handle the given placeholder expression kind. Return170 /// true if the source expression has the appropriate placeholder171 /// kind. A placeholder can only be claimed once.172 bool claimPlaceholder(BuiltinType::Kind K) {173 if (PlaceholderKind != K) return false;174 175 PlaceholderKind = (BuiltinType::Kind) 0;176 return true;177 }178 179 bool isPlaceholder() const {180 return PlaceholderKind != 0;181 }182 bool isPlaceholder(BuiltinType::Kind K) const {183 return PlaceholderKind == K;184 }185 186 // Language specific cast restrictions for address spaces.187 void checkAddressSpaceCast(QualType SrcType, QualType DestType);188 189 void checkCastAlign() {190 Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);191 }192 193 void checkObjCConversion(CheckedConversionKind CCK,194 bool IsReinterpretCast = false) {195 assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers());196 197 Expr *src = SrcExpr.get();198 if (Self.ObjC().CheckObjCConversion(199 OpRange, DestType, src, CCK, true, false, BO_PtrMemD,200 IsReinterpretCast) == SemaObjC::ACR_unbridged)201 IsARCUnbridgedCast = true;202 SrcExpr = src;203 }204 205 void checkQualifiedDestType() {206 // Destination type may not be qualified with __ptrauth.207 if (DestType.getPointerAuth()) {208 Self.Diag(DestRange.getBegin(), diag::err_ptrauth_qualifier_cast)209 << DestType << DestRange;210 }211 }212 213 /// Check for and handle non-overload placeholder expressions.214 void checkNonOverloadPlaceholders() {215 if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))216 return;217 218 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());219 if (SrcExpr.isInvalid())220 return;221 PlaceholderKind = (BuiltinType::Kind) 0;222 }223 };224 225 void CheckNoDeref(Sema &S, const QualType FromType, const QualType ToType,226 SourceLocation OpLoc) {227 if (const auto *PtrType = dyn_cast<PointerType>(FromType)) {228 if (PtrType->getPointeeType()->hasAttr(attr::NoDeref)) {229 if (const auto *DestType = dyn_cast<PointerType>(ToType)) {230 if (!DestType->getPointeeType()->hasAttr(attr::NoDeref)) {231 S.Diag(OpLoc, diag::warn_noderef_to_dereferenceable_pointer);232 }233 }234 }235 }236 }237 238 struct CheckNoDerefRAII {239 CheckNoDerefRAII(CastOperation &Op) : Op(Op) {}240 ~CheckNoDerefRAII() {241 if (!Op.SrcExpr.isInvalid())242 CheckNoDeref(Op.Self, Op.SrcExpr.get()->getType(), Op.ResultType,243 Op.OpRange.getBegin());244 }245 246 CastOperation &Op;247 };248}249 250static void DiagnoseCastQual(Sema &Self, const ExprResult &SrcExpr,251 QualType DestType);252 253// The Try functions attempt a specific way of casting. If they succeed, they254// return TC_Success. If their way of casting is not appropriate for the given255// arguments, they return TC_NotApplicable and *may* set diag to a diagnostic256// to emit if no other way succeeds. If their way of casting is appropriate but257// fails, they return TC_Failed and *must* set diag; they can set it to 0 if258// they emit a specialized diagnostic.259// All diagnostics returned by these functions must expect the same three260// arguments:261// %0: Cast Type (a value from the CastType enumeration)262// %1: Source Type263// %2: Destination Type264static TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr,265 QualType DestType, bool CStyle,266 SourceRange OpRange, CastKind &Kind,267 CXXCastPath &BasePath,268 unsigned &msg);269static TryCastResult270TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,271 bool CStyle, CastOperation::OpRangeType OpRange,272 unsigned &msg, CastKind &Kind,273 CXXCastPath &BasePath);274static TryCastResult275TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType,276 bool CStyle, CastOperation::OpRangeType OpRange,277 unsigned &msg, CastKind &Kind, CXXCastPath &BasePath);278static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,279 CanQualType DestType, bool CStyle,280 CastOperation::OpRangeType OpRange,281 QualType OrigSrcType,282 QualType OrigDestType, unsigned &msg,283 CastKind &Kind, CXXCastPath &BasePath);284static TryCastResult285TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType,286 QualType DestType, bool CStyle,287 CastOperation::OpRangeType OpRange, unsigned &msg,288 CastKind &Kind, CXXCastPath &BasePath);289 290static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr,291 QualType DestType,292 CheckedConversionKind CCK,293 CastOperation::OpRangeType OpRange,294 unsigned &msg, CastKind &Kind,295 bool ListInitialization);296static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,297 QualType DestType, CheckedConversionKind CCK,298 CastOperation::OpRangeType OpRange,299 unsigned &msg, CastKind &Kind,300 CXXCastPath &BasePath,301 bool ListInitialization);302static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr,303 QualType DestType, bool CStyle,304 unsigned &msg);305static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,306 QualType DestType, bool CStyle,307 CastOperation::OpRangeType OpRange,308 unsigned &msg, CastKind &Kind);309static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr,310 QualType DestType, bool CStyle,311 unsigned &msg, CastKind &Kind);312 313ExprResult314Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,315 SourceLocation LAngleBracketLoc, Declarator &D,316 SourceLocation RAngleBracketLoc,317 SourceLocation LParenLoc, Expr *E,318 SourceLocation RParenLoc) {319 320 assert(!D.isInvalidType());321 322 TypeSourceInfo *TInfo = GetTypeForDeclaratorCast(D, E->getType());323 if (D.isInvalidType())324 return ExprError();325 326 if (getLangOpts().CPlusPlus) {327 // Check that there are no default arguments (C++ only).328 CheckExtraCXXDefaultArguments(D);329 }330 331 return BuildCXXNamedCast(OpLoc, Kind, TInfo, E,332 SourceRange(LAngleBracketLoc, RAngleBracketLoc),333 SourceRange(LParenLoc, RParenLoc));334}335 336ExprResult337Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,338 TypeSourceInfo *DestTInfo, Expr *E,339 SourceRange AngleBrackets, SourceRange Parens) {340 ExprResult Ex = E;341 QualType DestType = DestTInfo->getType();342 343 // If the type is dependent, we won't do the semantic analysis now.344 bool TypeDependent =345 DestType->isDependentType() || Ex.get()->isTypeDependent();346 347 CastOperation Op(*this, DestType, E);348 Op.OpRange =349 CastOperation::OpRangeType(OpLoc, Parens.getBegin(), Parens.getEnd());350 Op.DestRange = AngleBrackets;351 352 Op.checkQualifiedDestType();353 354 switch (Kind) {355 default: llvm_unreachable("Unknown C++ cast!");356 357 case tok::kw_addrspace_cast:358 if (!TypeDependent) {359 Op.CheckAddrspaceCast();360 if (Op.SrcExpr.isInvalid())361 return ExprError();362 }363 return Op.complete(CXXAddrspaceCastExpr::Create(364 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),365 DestTInfo, OpLoc, Parens.getEnd(), AngleBrackets));366 367 case tok::kw_const_cast:368 if (!TypeDependent) {369 Op.CheckConstCast();370 if (Op.SrcExpr.isInvalid())371 return ExprError();372 DiscardMisalignedMemberAddress(DestType.getTypePtr(), E);373 }374 return Op.complete(CXXConstCastExpr::Create(Context, Op.ResultType,375 Op.ValueKind, Op.SrcExpr.get(), DestTInfo,376 OpLoc, Parens.getEnd(),377 AngleBrackets));378 379 case tok::kw_dynamic_cast: {380 // dynamic_cast is not supported in C++ for OpenCL.381 if (getLangOpts().OpenCLCPlusPlus) {382 return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported)383 << "dynamic_cast");384 }385 386 if (!TypeDependent) {387 Op.CheckDynamicCast();388 if (Op.SrcExpr.isInvalid())389 return ExprError();390 }391 return Op.complete(CXXDynamicCastExpr::Create(Context, Op.ResultType,392 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),393 &Op.BasePath, DestTInfo,394 OpLoc, Parens.getEnd(),395 AngleBrackets));396 }397 case tok::kw_reinterpret_cast: {398 if (!TypeDependent) {399 Op.CheckReinterpretCast();400 if (Op.SrcExpr.isInvalid())401 return ExprError();402 DiscardMisalignedMemberAddress(DestType.getTypePtr(), E);403 }404 return Op.complete(CXXReinterpretCastExpr::Create(Context, Op.ResultType,405 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),406 nullptr, DestTInfo, OpLoc,407 Parens.getEnd(),408 AngleBrackets));409 }410 case tok::kw_static_cast: {411 if (!TypeDependent) {412 Op.CheckStaticCast();413 if (Op.SrcExpr.isInvalid())414 return ExprError();415 DiscardMisalignedMemberAddress(DestType.getTypePtr(), E);416 }417 418 return Op.complete(CXXStaticCastExpr::Create(419 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),420 &Op.BasePath, DestTInfo, CurFPFeatureOverrides(), OpLoc,421 Parens.getEnd(), AngleBrackets));422 }423 }424}425 426ExprResult Sema::ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &D,427 ExprResult Operand,428 SourceLocation RParenLoc) {429 assert(!D.isInvalidType());430 431 TypeSourceInfo *TInfo = GetTypeForDeclaratorCast(D, Operand.get()->getType());432 if (D.isInvalidType())433 return ExprError();434 435 return BuildBuiltinBitCastExpr(KWLoc, TInfo, Operand.get(), RParenLoc);436}437 438ExprResult Sema::BuildBuiltinBitCastExpr(SourceLocation KWLoc,439 TypeSourceInfo *TSI, Expr *Operand,440 SourceLocation RParenLoc) {441 CastOperation Op(*this, TSI->getType(), Operand);442 Op.OpRange = CastOperation::OpRangeType(KWLoc, KWLoc, RParenLoc);443 TypeLoc TL = TSI->getTypeLoc();444 Op.DestRange = SourceRange(TL.getBeginLoc(), TL.getEndLoc());445 446 if (!Operand->isTypeDependent() && !TSI->getType()->isDependentType()) {447 Op.CheckBuiltinBitCast();448 if (Op.SrcExpr.isInvalid())449 return ExprError();450 }451 452 BuiltinBitCastExpr *BCE =453 new (Context) BuiltinBitCastExpr(Op.ResultType, Op.ValueKind, Op.Kind,454 Op.SrcExpr.get(), TSI, KWLoc, RParenLoc);455 return Op.complete(BCE);456}457 458/// Try to diagnose a failed overloaded cast. Returns true if459/// diagnostics were emitted.460static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT,461 CastOperation::OpRangeType range,462 Expr *src, QualType destType,463 bool listInitialization) {464 switch (CT) {465 // These cast kinds don't consider user-defined conversions.466 case CT_Const:467 case CT_Reinterpret:468 case CT_Dynamic:469 case CT_Addrspace:470 return false;471 472 // These do.473 case CT_Static:474 case CT_CStyle:475 case CT_Functional:476 break;477 }478 479 QualType srcType = src->getType();480 if (!destType->isRecordType() && !srcType->isRecordType())481 return false;482 483 InitializedEntity entity = InitializedEntity::InitializeTemporary(destType);484 InitializationKind initKind =485 (CT == CT_CStyle) ? InitializationKind::CreateCStyleCast(486 range.getBegin(), range, listInitialization)487 : (CT == CT_Functional)488 ? InitializationKind::CreateFunctionalCast(489 range.getBegin(), range.getParenRange(), listInitialization)490 : InitializationKind::CreateCast(/*type range?*/ range);491 InitializationSequence sequence(S, entity, initKind, src);492 493 // It could happen that a constructor failed to be used because494 // it requires a temporary of a broken type. Still, it will be found when495 // looking for a match.496 if (!sequence.Failed())497 return false;498 499 switch (sequence.getFailureKind()) {500 default: return false;501 502 case InitializationSequence::FK_ParenthesizedListInitFailed:503 // In C++20, if the underlying destination type is a RecordType, Clang504 // attempts to perform parentesized aggregate initialization if constructor505 // overload fails:506 //507 // C++20 [expr.static.cast]p4:508 // An expression E can be explicitly converted to a type T...if overload509 // resolution for a direct-initialization...would find at least one viable510 // function ([over.match.viable]), or if T is an aggregate type having a511 // first element X and there is an implicit conversion sequence from E to512 // the type of X.513 //514 // If that fails, then we'll generate the diagnostics from the failed515 // previous constructor overload attempt. Array initialization, however, is516 // not done after attempting constructor overloading, so we exit as there517 // won't be a failed overload result.518 if (destType->isArrayType())519 return false;520 break;521 case InitializationSequence::FK_ConstructorOverloadFailed:522 case InitializationSequence::FK_UserConversionOverloadFailed:523 break;524 }525 526 OverloadCandidateSet &candidates = sequence.getFailedCandidateSet();527 528 unsigned msg = 0;529 OverloadCandidateDisplayKind howManyCandidates = OCD_AllCandidates;530 531 switch (sequence.getFailedOverloadResult()) {532 case OR_Success: llvm_unreachable("successful failed overload");533 case OR_No_Viable_Function:534 if (candidates.empty())535 msg = diag::err_ovl_no_conversion_in_cast;536 else537 msg = diag::err_ovl_no_viable_conversion_in_cast;538 howManyCandidates = OCD_AllCandidates;539 break;540 541 case OR_Ambiguous:542 msg = diag::err_ovl_ambiguous_conversion_in_cast;543 howManyCandidates = OCD_AmbiguousCandidates;544 break;545 546 case OR_Deleted: {547 OverloadCandidateSet::iterator Best;548 [[maybe_unused]] OverloadingResult Res =549 candidates.BestViableFunction(S, range.getBegin(), Best);550 assert(Res == OR_Deleted && "Inconsistent overload resolution");551 552 StringLiteral *Msg = Best->Function->getDeletedMessage();553 candidates.NoteCandidates(554 PartialDiagnosticAt(range.getBegin(),555 S.PDiag(diag::err_ovl_deleted_conversion_in_cast)556 << CT << srcType << destType << (Msg != nullptr)557 << (Msg ? Msg->getString() : StringRef())558 << range << src->getSourceRange()),559 S, OCD_ViableCandidates, src);560 return true;561 }562 }563 564 candidates.NoteCandidates(565 PartialDiagnosticAt(range.getBegin(),566 S.PDiag(msg) << CT << srcType << destType << range567 << src->getSourceRange()),568 S, howManyCandidates, src);569 570 return true;571}572 573/// Diagnose a failed cast.574static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType,575 CastOperation::OpRangeType opRange, Expr *src,576 QualType destType, bool listInitialization) {577 if (msg == diag::err_bad_cxx_cast_generic &&578 tryDiagnoseOverloadedCast(S, castType, opRange, src, destType,579 listInitialization))580 return;581 582 S.Diag(opRange.getBegin(), msg) << castType583 << src->getType() << destType << opRange << src->getSourceRange();584 585 // Detect if both types are (ptr to) class, and note any incompleteness.586 int DifferentPtrness = 0;587 QualType From = destType;588 if (auto Ptr = From->getAs<PointerType>()) {589 From = Ptr->getPointeeType();590 DifferentPtrness++;591 }592 QualType To = src->getType();593 if (auto Ptr = To->getAs<PointerType>()) {594 To = Ptr->getPointeeType();595 DifferentPtrness--;596 }597 if (!DifferentPtrness) {598 if (auto *DeclFrom = From->getAsCXXRecordDecl(),599 *DeclTo = To->getAsCXXRecordDecl();600 DeclFrom && DeclTo) {601 if (!DeclFrom->isCompleteDefinition())602 S.Diag(DeclFrom->getLocation(), diag::note_type_incomplete) << DeclFrom;603 if (!DeclTo->isCompleteDefinition())604 S.Diag(DeclTo->getLocation(), diag::note_type_incomplete) << DeclTo;605 }606 }607}608 609namespace {610/// The kind of unwrapping we did when determining whether a conversion casts611/// away constness.612enum CastAwayConstnessKind {613 /// The conversion does not cast away constness.614 CACK_None = 0,615 /// We unwrapped similar types.616 CACK_Similar = 1,617 /// We unwrapped dissimilar types with similar representations (eg, a pointer618 /// versus an Objective-C object pointer).619 CACK_SimilarKind = 2,620 /// We unwrapped representationally-unrelated types, such as a pointer versus621 /// a pointer-to-member.622 CACK_Incoherent = 3,623};624}625 626/// Unwrap one level of types for CastsAwayConstness.627///628/// Like Sema::UnwrapSimilarTypes, this removes one level of indirection from629/// both types, provided that they're both pointer-like or array-like. Unlike630/// the Sema function, doesn't care if the unwrapped pieces are related.631///632/// This function may remove additional levels as necessary for correctness:633/// the resulting T1 is unwrapped sufficiently that it is never an array type,634/// so that its qualifiers can be directly compared to those of T2 (which will635/// have the combined set of qualifiers from all indermediate levels of T2),636/// as (effectively) required by [expr.const.cast]p7 replacing T1's qualifiers637/// with those from T2.638static CastAwayConstnessKind639unwrapCastAwayConstnessLevel(ASTContext &Context, QualType &T1, QualType &T2) {640 enum { None, Ptr, MemPtr, BlockPtr, Array };641 auto Classify = [](QualType T) {642 if (T->isAnyPointerType()) return Ptr;643 if (T->isMemberPointerType()) return MemPtr;644 if (T->isBlockPointerType()) return BlockPtr;645 // We somewhat-arbitrarily don't look through VLA types here. This is at646 // least consistent with the behavior of UnwrapSimilarTypes.647 if (T->isConstantArrayType() || T->isIncompleteArrayType()) return Array;648 return None;649 };650 651 auto Unwrap = [&](QualType T) {652 if (auto *AT = Context.getAsArrayType(T))653 return AT->getElementType();654 return T->getPointeeType();655 };656 657 CastAwayConstnessKind Kind;658 659 if (T2->isReferenceType()) {660 // Special case: if the destination type is a reference type, unwrap it as661 // the first level. (The source will have been an lvalue expression in this662 // case, so there is no corresponding "reference to" in T1 to remove.) This663 // simulates removing a "pointer to" from both sides.664 T2 = T2->getPointeeType();665 Kind = CastAwayConstnessKind::CACK_Similar;666 } else if (Context.UnwrapSimilarTypes(T1, T2)) {667 Kind = CastAwayConstnessKind::CACK_Similar;668 } else {669 // Try unwrapping mismatching levels.670 int T1Class = Classify(T1);671 if (T1Class == None)672 return CastAwayConstnessKind::CACK_None;673 674 int T2Class = Classify(T2);675 if (T2Class == None)676 return CastAwayConstnessKind::CACK_None;677 678 T1 = Unwrap(T1);679 T2 = Unwrap(T2);680 Kind = T1Class == T2Class ? CastAwayConstnessKind::CACK_SimilarKind681 : CastAwayConstnessKind::CACK_Incoherent;682 }683 684 // We've unwrapped at least one level. If the resulting T1 is a (possibly685 // multidimensional) array type, any qualifier on any matching layer of686 // T2 is considered to correspond to T1. Decompose down to the element687 // type of T1 so that we can compare properly.688 while (true) {689 Context.UnwrapSimilarArrayTypes(T1, T2);690 691 if (Classify(T1) != Array)692 break;693 694 auto T2Class = Classify(T2);695 if (T2Class == None)696 break;697 698 if (T2Class != Array)699 Kind = CastAwayConstnessKind::CACK_Incoherent;700 else if (Kind != CastAwayConstnessKind::CACK_Incoherent)701 Kind = CastAwayConstnessKind::CACK_SimilarKind;702 703 T1 = Unwrap(T1);704 T2 = Unwrap(T2).withCVRQualifiers(T2.getCVRQualifiers());705 }706 707 return Kind;708}709 710/// Check if the pointer conversion from SrcType to DestType casts away711/// constness as defined in C++ [expr.const.cast]. This is used by the cast712/// checkers. Both arguments must denote pointer (possibly to member) types.713///714/// \param CheckCVR Whether to check for const/volatile/restrict qualifiers.715/// \param CheckObjCLifetime Whether to check Objective-C lifetime qualifiers.716static CastAwayConstnessKind717CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType,718 bool CheckCVR, bool CheckObjCLifetime,719 QualType *TheOffendingSrcType = nullptr,720 QualType *TheOffendingDestType = nullptr,721 Qualifiers *CastAwayQualifiers = nullptr) {722 // If the only checking we care about is for Objective-C lifetime qualifiers,723 // and we're not in ObjC mode, there's nothing to check.724 if (!CheckCVR && CheckObjCLifetime && !Self.Context.getLangOpts().ObjC)725 return CastAwayConstnessKind::CACK_None;726 727 if (!DestType->isReferenceType()) {728 assert((SrcType->isAnyPointerType() || SrcType->isMemberPointerType() ||729 SrcType->isBlockPointerType()) &&730 "Source type is not pointer or pointer to member.");731 assert((DestType->isAnyPointerType() || DestType->isMemberPointerType() ||732 DestType->isBlockPointerType()) &&733 "Destination type is not pointer or pointer to member.");734 }735 736 QualType UnwrappedSrcType = Self.Context.getCanonicalType(SrcType),737 UnwrappedDestType = Self.Context.getCanonicalType(DestType);738 739 // Find the qualifiers. We only care about cvr-qualifiers for the740 // purpose of this check, because other qualifiers (address spaces,741 // Objective-C GC, etc.) are part of the type's identity.742 QualType PrevUnwrappedSrcType = UnwrappedSrcType;743 QualType PrevUnwrappedDestType = UnwrappedDestType;744 auto WorstKind = CastAwayConstnessKind::CACK_Similar;745 bool AllConstSoFar = true;746 while (auto Kind = unwrapCastAwayConstnessLevel(747 Self.Context, UnwrappedSrcType, UnwrappedDestType)) {748 // Track the worst kind of unwrap we needed to do before we found a749 // problem.750 if (Kind > WorstKind)751 WorstKind = Kind;752 753 // Determine the relevant qualifiers at this level.754 Qualifiers SrcQuals, DestQuals;755 Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals);756 Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals);757 758 // We do not meaningfully track object const-ness of Objective-C object759 // types. Remove const from the source type if either the source or760 // the destination is an Objective-C object type.761 if (UnwrappedSrcType->isObjCObjectType() ||762 UnwrappedDestType->isObjCObjectType())763 SrcQuals.removeConst();764 765 if (CheckCVR) {766 Qualifiers SrcCvrQuals =767 Qualifiers::fromCVRMask(SrcQuals.getCVRQualifiers());768 Qualifiers DestCvrQuals =769 Qualifiers::fromCVRMask(DestQuals.getCVRQualifiers());770 771 if (SrcCvrQuals != DestCvrQuals) {772 if (CastAwayQualifiers)773 *CastAwayQualifiers = SrcCvrQuals - DestCvrQuals;774 775 // If we removed a cvr-qualifier, this is casting away 'constness'.776 if (!DestCvrQuals.compatiblyIncludes(SrcCvrQuals,777 Self.getASTContext())) {778 if (TheOffendingSrcType)779 *TheOffendingSrcType = PrevUnwrappedSrcType;780 if (TheOffendingDestType)781 *TheOffendingDestType = PrevUnwrappedDestType;782 return WorstKind;783 }784 785 // If any prior level was not 'const', this is also casting away786 // 'constness'. We noted the outermost type missing a 'const' already.787 if (!AllConstSoFar)788 return WorstKind;789 }790 }791 792 if (CheckObjCLifetime &&793 !DestQuals.compatiblyIncludesObjCLifetime(SrcQuals))794 return WorstKind;795 796 // If we found our first non-const-qualified type, this may be the place797 // where things start to go wrong.798 if (AllConstSoFar && !DestQuals.hasConst()) {799 AllConstSoFar = false;800 if (TheOffendingSrcType)801 *TheOffendingSrcType = PrevUnwrappedSrcType;802 if (TheOffendingDestType)803 *TheOffendingDestType = PrevUnwrappedDestType;804 }805 806 PrevUnwrappedSrcType = UnwrappedSrcType;807 PrevUnwrappedDestType = UnwrappedDestType;808 }809 810 return CastAwayConstnessKind::CACK_None;811}812 813static TryCastResult getCastAwayConstnessCastKind(CastAwayConstnessKind CACK,814 unsigned &DiagID) {815 switch (CACK) {816 case CastAwayConstnessKind::CACK_None:817 llvm_unreachable("did not cast away constness");818 819 case CastAwayConstnessKind::CACK_Similar:820 // FIXME: Accept these as an extension too?821 case CastAwayConstnessKind::CACK_SimilarKind:822 DiagID = diag::err_bad_cxx_cast_qualifiers_away;823 return TC_Failed;824 825 case CastAwayConstnessKind::CACK_Incoherent:826 DiagID = diag::ext_bad_cxx_cast_qualifiers_away_incoherent;827 return TC_Extension;828 }829 830 llvm_unreachable("unexpected cast away constness kind");831}832 833/// CheckDynamicCast - Check that a dynamic_cast\<DestType\>(SrcExpr) is valid.834/// Refer to C++ 5.2.7 for details. Dynamic casts are used mostly for runtime-835/// checked downcasts in class hierarchies.836void CastOperation::CheckDynamicCast() {837 CheckNoDerefRAII NoderefCheck(*this);838 839 if (ValueKind == VK_PRValue)840 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());841 else if (isPlaceholder())842 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());843 if (SrcExpr.isInvalid()) // if conversion failed, don't report another error844 return;845 846 QualType OrigSrcType = SrcExpr.get()->getType();847 QualType DestType = Self.Context.getCanonicalType(this->DestType);848 849 // C++ 5.2.7p1: T shall be a pointer or reference to a complete class type,850 // or "pointer to cv void".851 852 QualType DestPointee;853 const PointerType *DestPointer = DestType->getAs<PointerType>();854 const ReferenceType *DestReference = nullptr;855 if (DestPointer) {856 DestPointee = DestPointer->getPointeeType();857 } else if ((DestReference = DestType->getAs<ReferenceType>())) {858 DestPointee = DestReference->getPointeeType();859 } else {860 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)861 << this->DestType << DestRange;862 SrcExpr = ExprError();863 return;864 }865 866 const auto *DestRecord = DestPointee->getAsCanonical<RecordType>();867 if (DestPointee->isVoidType()) {868 assert(DestPointer && "Reference to void is not possible");869 } else if (DestRecord) {870 if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee,871 diag::err_bad_cast_incomplete,872 DestRange)) {873 SrcExpr = ExprError();874 return;875 }876 } else {877 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)878 << DestPointee.getUnqualifiedType() << DestRange;879 SrcExpr = ExprError();880 return;881 }882 883 // C++0x 5.2.7p2: If T is a pointer type, v shall be an rvalue of a pointer to884 // complete class type, [...]. If T is an lvalue reference type, v shall be885 // an lvalue of a complete class type, [...]. If T is an rvalue reference886 // type, v shall be an expression having a complete class type, [...]887 QualType SrcType = Self.Context.getCanonicalType(OrigSrcType);888 QualType SrcPointee;889 if (DestPointer) {890 if (const PointerType *SrcPointer = SrcType->getAs<PointerType>()) {891 SrcPointee = SrcPointer->getPointeeType();892 } else {893 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)894 << OrigSrcType << this->DestType << SrcExpr.get()->getSourceRange();895 SrcExpr = ExprError();896 return;897 }898 } else if (DestReference->isLValueReferenceType()) {899 if (!SrcExpr.get()->isLValue()) {900 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)901 << CT_Dynamic << OrigSrcType << this->DestType << OpRange;902 }903 SrcPointee = SrcType;904 } else {905 // If we're dynamic_casting from a prvalue to an rvalue reference, we need906 // to materialize the prvalue before we bind the reference to it.907 if (SrcExpr.get()->isPRValue())908 SrcExpr = Self.CreateMaterializeTemporaryExpr(909 SrcType, SrcExpr.get(), /*IsLValueReference*/ false);910 SrcPointee = SrcType;911 }912 913 const auto *SrcRecord = SrcPointee->getAsCanonical<RecordType>();914 if (SrcRecord) {915 if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,916 diag::err_bad_cast_incomplete,917 SrcExpr.get())) {918 SrcExpr = ExprError();919 return;920 }921 } else {922 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)923 << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();924 SrcExpr = ExprError();925 return;926 }927 928 assert((DestPointer || DestReference) &&929 "Bad destination non-ptr/ref slipped through.");930 assert((DestRecord || DestPointee->isVoidType()) &&931 "Bad destination pointee slipped through.");932 assert(SrcRecord && "Bad source pointee slipped through.");933 934 // C++ 5.2.7p1: The dynamic_cast operator shall not cast away constness.935 if (!DestPointee.isAtLeastAsQualifiedAs(SrcPointee, Self.getASTContext())) {936 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away)937 << CT_Dynamic << OrigSrcType << this->DestType << OpRange;938 SrcExpr = ExprError();939 return;940 }941 942 // C++ 5.2.7p3: If the type of v is the same as the required result type,943 // [except for cv].944 if (DestRecord == SrcRecord) {945 Kind = CK_NoOp;946 return;947 }948 949 // C++ 5.2.7p5950 // Upcasts are resolved statically.951 if (DestRecord &&952 Self.IsDerivedFrom(OpRange.getBegin(), SrcPointee, DestPointee)) {953 if (Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,954 OpRange.getBegin(), OpRange,955 &BasePath)) {956 SrcExpr = ExprError();957 return;958 }959 960 Kind = CK_DerivedToBase;961 return;962 }963 964 // C++ 5.2.7p6: Otherwise, v shall be [polymorphic].965 const RecordDecl *SrcDecl = SrcRecord->getDecl()->getDefinition();966 assert(SrcDecl && "Definition missing");967 if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {968 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)969 << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();970 SrcExpr = ExprError();971 }972 973 // dynamic_cast is not available with -fno-rtti.974 // As an exception, dynamic_cast to void* is available because it doesn't975 // use RTTI.976 if (!Self.getLangOpts().RTTI && !DestPointee->isVoidType()) {977 Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti);978 SrcExpr = ExprError();979 return;980 }981 982 // Warns when dynamic_cast is used with RTTI data disabled.983 if (!Self.getLangOpts().RTTIData) {984 bool MicrosoftABI =985 Self.getASTContext().getTargetInfo().getCXXABI().isMicrosoft();986 bool isClangCL = Self.getDiagnostics().getDiagnosticOptions().getFormat() ==987 DiagnosticOptions::MSVC;988 if (MicrosoftABI || !DestPointee->isVoidType())989 Self.Diag(OpRange.getBegin(),990 diag::warn_no_dynamic_cast_with_rtti_disabled)991 << isClangCL;992 }993 994 // For a dynamic_cast to a final type, IR generation might emit a reference995 // to the vtable.996 if (DestRecord) {997 auto *DestDecl = DestRecord->getAsCXXRecordDecl();998 if (DestDecl->isEffectivelyFinal())999 Self.MarkVTableUsed(OpRange.getBegin(), DestDecl);1000 }1001 1002 // Done. Everything else is run-time checks.1003 Kind = CK_Dynamic;1004}1005 1006/// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid.1007/// Refer to C++ 5.2.11 for details. const_cast is typically used in code1008/// like this:1009/// const char *str = "literal";1010/// legacy_function(const_cast\<char*\>(str));1011void CastOperation::CheckConstCast() {1012 CheckNoDerefRAII NoderefCheck(*this);1013 1014 if (ValueKind == VK_PRValue)1015 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());1016 else if (isPlaceholder())1017 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());1018 if (SrcExpr.isInvalid()) // if conversion failed, don't report another error1019 return;1020 1021 unsigned msg = diag::err_bad_cxx_cast_generic;1022 auto TCR = TryConstCast(Self, SrcExpr, DestType, /*CStyle*/ false, msg);1023 if (TCR != TC_Success && msg != 0) {1024 Self.Diag(OpRange.getBegin(), msg) << CT_Const1025 << SrcExpr.get()->getType() << DestType << OpRange;1026 }1027 if (!isValidCast(TCR))1028 SrcExpr = ExprError();1029}1030 1031void CastOperation::CheckAddrspaceCast() {1032 unsigned msg = diag::err_bad_cxx_cast_generic;1033 auto TCR =1034 TryAddressSpaceCast(Self, SrcExpr, DestType, /*CStyle*/ false, msg, Kind);1035 if (TCR != TC_Success && msg != 0) {1036 Self.Diag(OpRange.getBegin(), msg)1037 << CT_Addrspace << SrcExpr.get()->getType() << DestType << OpRange;1038 }1039 if (!isValidCast(TCR))1040 SrcExpr = ExprError();1041}1042 1043/// Check that a reinterpret_cast\<DestType\>(SrcExpr) is not used as upcast1044/// or downcast between respective pointers or references.1045static void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr,1046 QualType DestType,1047 CastOperation::OpRangeType OpRange) {1048 QualType SrcType = SrcExpr->getType();1049 // When casting from pointer or reference, get pointee type; use original1050 // type otherwise.1051 const CXXRecordDecl *SrcPointeeRD = SrcType->getPointeeCXXRecordDecl();1052 const CXXRecordDecl *SrcRD =1053 SrcPointeeRD ? SrcPointeeRD : SrcType->getAsCXXRecordDecl();1054 1055 // Examining subobjects for records is only possible if the complete and1056 // valid definition is available. Also, template instantiation is not1057 // allowed here.1058 if (!SrcRD || !SrcRD->isCompleteDefinition() || SrcRD->isInvalidDecl())1059 return;1060 1061 const CXXRecordDecl *DestRD = DestType->getPointeeCXXRecordDecl();1062 1063 if (!DestRD || !DestRD->isCompleteDefinition() || DestRD->isInvalidDecl())1064 return;1065 1066 enum {1067 ReinterpretUpcast,1068 ReinterpretDowncast1069 } ReinterpretKind;1070 1071 CXXBasePaths BasePaths;1072 1073 if (SrcRD->isDerivedFrom(DestRD, BasePaths))1074 ReinterpretKind = ReinterpretUpcast;1075 else if (DestRD->isDerivedFrom(SrcRD, BasePaths))1076 ReinterpretKind = ReinterpretDowncast;1077 else1078 return;1079 1080 bool VirtualBase = true;1081 bool NonZeroOffset = false;1082 for (CXXBasePaths::const_paths_iterator I = BasePaths.begin(),1083 E = BasePaths.end();1084 I != E; ++I) {1085 const CXXBasePath &Path = *I;1086 CharUnits Offset = CharUnits::Zero();1087 bool IsVirtual = false;1088 for (CXXBasePath::const_iterator IElem = Path.begin(), EElem = Path.end();1089 IElem != EElem; ++IElem) {1090 IsVirtual = IElem->Base->isVirtual();1091 if (IsVirtual)1092 break;1093 const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl();1094 assert(BaseRD && "Base type should be a valid unqualified class type");1095 // Don't check if any base has invalid declaration or has no definition1096 // since it has no layout info.1097 const CXXRecordDecl *Class = IElem->Class,1098 *ClassDefinition = Class->getDefinition();1099 if (Class->isInvalidDecl() || !ClassDefinition ||1100 !ClassDefinition->isCompleteDefinition())1101 return;1102 1103 const ASTRecordLayout &DerivedLayout =1104 Self.Context.getASTRecordLayout(Class);1105 Offset += DerivedLayout.getBaseClassOffset(BaseRD);1106 }1107 if (!IsVirtual) {1108 // Don't warn if any path is a non-virtually derived base at offset zero.1109 if (Offset.isZero())1110 return;1111 // Offset makes sense only for non-virtual bases.1112 else1113 NonZeroOffset = true;1114 }1115 VirtualBase = VirtualBase && IsVirtual;1116 }1117 1118 (void) NonZeroOffset; // Silence set but not used warning.1119 assert((VirtualBase || NonZeroOffset) &&1120 "Should have returned if has non-virtual base with zero offset");1121 1122 QualType BaseType =1123 ReinterpretKind == ReinterpretUpcast? DestType : SrcType;1124 QualType DerivedType =1125 ReinterpretKind == ReinterpretUpcast? SrcType : DestType;1126 1127 SourceLocation BeginLoc = OpRange.getBegin();1128 Self.Diag(BeginLoc, diag::warn_reinterpret_different_from_static)1129 << DerivedType << BaseType << !VirtualBase << int(ReinterpretKind)1130 << OpRange;1131 Self.Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static)1132 << int(ReinterpretKind)1133 << FixItHint::CreateReplacement(BeginLoc, "static_cast");1134}1135 1136static bool argTypeIsABIEquivalent(QualType SrcType, QualType DestType,1137 ASTContext &Context) {1138 if (SrcType->isPointerType() && DestType->isPointerType())1139 return true;1140 1141 // Allow integral type mismatch if their size are equal.1142 if ((SrcType->isIntegralType(Context) || SrcType->isEnumeralType()) &&1143 (DestType->isIntegralType(Context) || DestType->isEnumeralType()))1144 if (Context.getTypeSizeInChars(SrcType) ==1145 Context.getTypeSizeInChars(DestType))1146 return true;1147 1148 return Context.hasSameUnqualifiedType(SrcType, DestType);1149}1150 1151static unsigned int checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr,1152 QualType DestType) {1153 unsigned int DiagID = 0;1154 const unsigned int DiagList[] = {diag::warn_cast_function_type_strict,1155 diag::warn_cast_function_type};1156 for (auto ID : DiagList) {1157 if (!Self.Diags.isIgnored(ID, SrcExpr.get()->getExprLoc())) {1158 DiagID = ID;1159 break;1160 }1161 }1162 if (!DiagID)1163 return 0;1164 1165 QualType SrcType = SrcExpr.get()->getType();1166 const FunctionType *SrcFTy = nullptr;1167 const FunctionType *DstFTy = nullptr;1168 if (((SrcType->isBlockPointerType() || SrcType->isFunctionPointerType()) &&1169 DestType->isFunctionPointerType()) ||1170 (SrcType->isMemberFunctionPointerType() &&1171 DestType->isMemberFunctionPointerType())) {1172 SrcFTy = SrcType->getPointeeType()->castAs<FunctionType>();1173 DstFTy = DestType->getPointeeType()->castAs<FunctionType>();1174 } else if (SrcType->isFunctionType() && DestType->isFunctionReferenceType()) {1175 SrcFTy = SrcType->castAs<FunctionType>();1176 DstFTy = DestType.getNonReferenceType()->castAs<FunctionType>();1177 } else {1178 return 0;1179 }1180 assert(SrcFTy && DstFTy);1181 1182 if (Self.Context.hasSameType(SrcFTy, DstFTy))1183 return 0;1184 1185 // For strict checks, ensure we have an exact match.1186 if (DiagID == diag::warn_cast_function_type_strict)1187 return DiagID;1188 1189 auto IsVoidVoid = [](const FunctionType *T) {1190 if (!T->getReturnType()->isVoidType())1191 return false;1192 if (const auto *PT = T->getAs<FunctionProtoType>())1193 return !PT->isVariadic() && PT->getNumParams() == 0;1194 return false;1195 };1196 1197 auto IsFarProc = [](const FunctionType *T) {1198 // The definition of FARPROC depends on the platform in terms of its return1199 // type, which could be int, or long long, etc. We'll look for a source1200 // signature for: <integer type> (*)() and call that "close enough" to1201 // FARPROC to be sufficient to silence the diagnostic. This is similar to1202 // how we allow casts between function pointers and void * for supporting1203 // dlsym.1204 // Note: we could check for __stdcall on the function pointer as well, but1205 // that seems like splitting hairs.1206 if (!T->getReturnType()->isIntegerType())1207 return false;1208 if (const auto *PT = T->getAs<FunctionProtoType>())1209 return !PT->isVariadic() && PT->getNumParams() == 0;1210 return true;1211 };1212 1213 // Skip if either function type is void(*)(void)1214 if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy))1215 return 0;1216 1217 // On Windows, GetProcAddress() returns a FARPROC, which is a typedef for a1218 // function pointer type (with no prototype, in C). We don't want to diagnose1219 // this case so we don't diagnose idiomatic code on Windows.1220 if (Self.getASTContext().getTargetInfo().getTriple().isOSWindows() &&1221 IsFarProc(SrcFTy))1222 return 0;1223 1224 // Check return type.1225 if (!argTypeIsABIEquivalent(SrcFTy->getReturnType(), DstFTy->getReturnType(),1226 Self.Context))1227 return DiagID;1228 1229 // Check if either has unspecified number of parameters1230 if (SrcFTy->isFunctionNoProtoType() || DstFTy->isFunctionNoProtoType())1231 return 0;1232 1233 // Check parameter types.1234 1235 const auto *SrcFPTy = cast<FunctionProtoType>(SrcFTy);1236 const auto *DstFPTy = cast<FunctionProtoType>(DstFTy);1237 1238 // In a cast involving function types with a variable argument list only the1239 // types of initial arguments that are provided are considered.1240 unsigned NumParams = SrcFPTy->getNumParams();1241 unsigned DstNumParams = DstFPTy->getNumParams();1242 if (NumParams > DstNumParams) {1243 if (!DstFPTy->isVariadic())1244 return DiagID;1245 NumParams = DstNumParams;1246 } else if (NumParams < DstNumParams) {1247 if (!SrcFPTy->isVariadic())1248 return DiagID;1249 }1250 1251 for (unsigned i = 0; i < NumParams; ++i)1252 if (!argTypeIsABIEquivalent(SrcFPTy->getParamType(i),1253 DstFPTy->getParamType(i), Self.Context))1254 return DiagID;1255 1256 return 0;1257}1258 1259/// CheckReinterpretCast - Check that a reinterpret_cast\<DestType\>(SrcExpr) is1260/// valid.1261/// Refer to C++ 5.2.10 for details. reinterpret_cast is typically used in code1262/// like this:1263/// char *bytes = reinterpret_cast\<char*\>(int_ptr);1264void CastOperation::CheckReinterpretCast() {1265 if (ValueKind == VK_PRValue && !isPlaceholder(BuiltinType::Overload))1266 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());1267 else1268 checkNonOverloadPlaceholders();1269 if (SrcExpr.isInvalid()) // if conversion failed, don't report another error1270 return;1271 1272 unsigned msg = diag::err_bad_cxx_cast_generic;1273 TryCastResult tcr =1274 TryReinterpretCast(Self, SrcExpr, DestType,1275 /*CStyle*/false, OpRange, msg, Kind);1276 if (tcr != TC_Success && msg != 0) {1277 if (SrcExpr.isInvalid()) // if conversion failed, don't report another error1278 return;1279 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {1280 //FIXME: &f<int>; is overloaded and resolvable1281 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload)1282 << OverloadExpr::find(SrcExpr.get()).Expression->getName()1283 << DestType << OpRange;1284 Self.NoteAllOverloadCandidates(SrcExpr.get());1285 1286 } else {1287 diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(),1288 DestType, /*listInitialization=*/false);1289 }1290 }1291 1292 if (isValidCast(tcr)) {1293 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())1294 checkObjCConversion(CheckedConversionKind::OtherCast,1295 /*IsReinterpretCast=*/true);1296 DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange);1297 1298 if (unsigned DiagID = checkCastFunctionType(Self, SrcExpr, DestType))1299 Self.Diag(OpRange.getBegin(), DiagID)1300 << SrcExpr.get()->getType() << DestType << OpRange;1301 } else {1302 SrcExpr = ExprError();1303 }1304}1305 1306 1307/// CheckStaticCast - Check that a static_cast\<DestType\>(SrcExpr) is valid.1308/// Refer to C++ 5.2.9 for details. Static casts are mostly used for making1309/// implicit conversions explicit and getting rid of data loss warnings.1310void CastOperation::CheckStaticCast() {1311 CheckNoDerefRAII NoderefCheck(*this);1312 1313 if (isPlaceholder()) {1314 checkNonOverloadPlaceholders();1315 if (SrcExpr.isInvalid())1316 return;1317 }1318 1319 // This test is outside everything else because it's the only case where1320 // a non-lvalue-reference target type does not lead to decay.1321 // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".1322 if (DestType->isVoidType()) {1323 Kind = CK_ToVoid;1324 1325 if (claimPlaceholder(BuiltinType::Overload)) {1326 Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,1327 false, // Decay Function to ptr1328 true, // Complain1329 OpRange, DestType, diag::err_bad_static_cast_overload);1330 if (SrcExpr.isInvalid())1331 return;1332 }1333 1334 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());1335 return;1336 }1337 1338 if (ValueKind == VK_PRValue && !DestType->isRecordType() &&1339 !isPlaceholder(BuiltinType::Overload)) {1340 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());1341 if (SrcExpr.isInvalid()) // if conversion failed, don't report another error1342 return;1343 }1344 1345 unsigned msg = diag::err_bad_cxx_cast_generic;1346 TryCastResult tcr =1347 TryStaticCast(Self, SrcExpr, DestType, CheckedConversionKind::OtherCast,1348 OpRange, msg, Kind, BasePath, /*ListInitialization=*/false);1349 if (tcr != TC_Success && msg != 0) {1350 if (SrcExpr.isInvalid())1351 return;1352 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {1353 OverloadExpr* oe = OverloadExpr::find(SrcExpr.get()).Expression;1354 Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)1355 << oe->getName() << DestType << OpRange1356 << oe->getQualifierLoc().getSourceRange();1357 Self.NoteAllOverloadCandidates(SrcExpr.get());1358 } else {1359 diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr.get(), DestType,1360 /*listInitialization=*/false);1361 }1362 }1363 1364 if (isValidCast(tcr)) {1365 if (Kind == CK_BitCast)1366 checkCastAlign();1367 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())1368 checkObjCConversion(CheckedConversionKind::OtherCast);1369 } else {1370 SrcExpr = ExprError();1371 }1372}1373 1374static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType) {1375 auto *SrcPtrType = SrcType->getAs<PointerType>();1376 if (!SrcPtrType)1377 return false;1378 auto *DestPtrType = DestType->getAs<PointerType>();1379 if (!DestPtrType)1380 return false;1381 return SrcPtrType->getPointeeType().getAddressSpace() !=1382 DestPtrType->getPointeeType().getAddressSpace();1383}1384 1385/// TryStaticCast - Check if a static cast can be performed, and do so if1386/// possible. If @p CStyle, ignore access restrictions on hierarchy casting1387/// and casting away constness.1388static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,1389 QualType DestType, CheckedConversionKind CCK,1390 CastOperation::OpRangeType OpRange,1391 unsigned &msg, CastKind &Kind,1392 CXXCastPath &BasePath,1393 bool ListInitialization) {1394 // Determine whether we have the semantics of a C-style cast.1395 bool CStyle = (CCK == CheckedConversionKind::CStyleCast ||1396 CCK == CheckedConversionKind::FunctionalCast);1397 1398 // The order the tests is not entirely arbitrary. There is one conversion1399 // that can be handled in two different ways. Given:1400 // struct A {};1401 // struct B : public A {1402 // B(); B(const A&);1403 // };1404 // const A &a = B();1405 // the cast static_cast<const B&>(a) could be seen as either a static1406 // reference downcast, or an explicit invocation of the user-defined1407 // conversion using B's conversion constructor.1408 // DR 427 specifies that the downcast is to be applied here.1409 1410 // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".1411 // Done outside this function.1412 1413 TryCastResult tcr;1414 1415 // C++ 5.2.9p5, reference downcast.1416 // See the function for details.1417 // DR 427 specifies that this is to be applied before paragraph 2.1418 tcr = TryStaticReferenceDowncast(Self, SrcExpr.get(), DestType, CStyle,1419 OpRange, msg, Kind, BasePath);1420 if (tcr != TC_NotApplicable)1421 return tcr;1422 1423 // C++11 [expr.static.cast]p3:1424 // A glvalue of type "cv1 T1" can be cast to type "rvalue reference to cv21425 // T2" if "cv2 T2" is reference-compatible with "cv1 T1".1426 tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, OpRange,1427 Kind, BasePath, msg);1428 if (tcr != TC_NotApplicable)1429 return tcr;1430 1431 // C++ 5.2.9p2: An expression e can be explicitly converted to a type T1432 // [...] if the declaration "T t(e);" is well-formed, [...].1433 tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CCK, OpRange, msg,1434 Kind, ListInitialization);1435 if (SrcExpr.isInvalid())1436 return TC_Failed;1437 if (tcr != TC_NotApplicable)1438 return tcr;1439 1440 // C++ 5.2.9p6: May apply the reverse of any standard conversion, except1441 // lvalue-to-rvalue, array-to-pointer, function-to-pointer, and boolean1442 // conversions, subject to further restrictions.1443 // Also, C++ 5.2.9p1 forbids casting away constness, which makes reversal1444 // of qualification conversions impossible. (In C++20, adding an array bound1445 // would be the reverse of a qualification conversion, but adding permission1446 // to add an array bound in a static_cast is a wording oversight.)1447 // In the CStyle case, the earlier attempt to const_cast should have taken1448 // care of reverse qualification conversions.1449 1450 QualType SrcType = Self.Context.getCanonicalType(SrcExpr.get()->getType());1451 1452 // C++0x 5.2.9p9: A value of a scoped enumeration type can be explicitly1453 // converted to an integral type. [...] A value of a scoped enumeration type1454 // can also be explicitly converted to a floating-point type [...].1455 if (const EnumType *Enum = dyn_cast<EnumType>(SrcType)) {1456 if (Enum->getDecl()->isScoped()) {1457 if (DestType->isBooleanType()) {1458 Kind = CK_IntegralToBoolean;1459 return TC_Success;1460 } else if (DestType->isIntegralType(Self.Context)) {1461 Kind = CK_IntegralCast;1462 return TC_Success;1463 } else if (DestType->isRealFloatingType()) {1464 Kind = CK_IntegralToFloating;1465 return TC_Success;1466 }1467 }1468 }1469 1470 // Reverse integral promotion/conversion. All such conversions are themselves1471 // again integral promotions or conversions and are thus already handled by1472 // p2 (TryDirectInitialization above).1473 // (Note: any data loss warnings should be suppressed.)1474 // The exception is the reverse of enum->integer, i.e. integer->enum (and1475 // enum->enum). See also C++ 5.2.9p7.1476 // The same goes for reverse floating point promotion/conversion and1477 // floating-integral conversions. Again, only floating->enum is relevant.1478 if (DestType->isEnumeralType()) {1479 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,1480 diag::err_bad_cast_incomplete)) {1481 SrcExpr = ExprError();1482 return TC_Failed;1483 }1484 if (SrcType->isIntegralOrEnumerationType()) {1485 // [expr.static.cast]p10 If the enumeration type has a fixed underlying1486 // type, the value is first converted to that type by integral conversion1487 const auto *ED = DestType->castAsEnumDecl();1488 Kind = ED->isFixed() && ED->getIntegerType()->isBooleanType()1489 ? CK_IntegralToBoolean1490 : CK_IntegralCast;1491 return TC_Success;1492 } else if (SrcType->isRealFloatingType()) {1493 Kind = CK_FloatingToIntegral;1494 return TC_Success;1495 }1496 }1497 1498 // Reverse pointer upcast. C++ 4.10p3 specifies pointer upcast.1499 // C++ 5.2.9p8 additionally disallows a cast path through virtual inheritance.1500 tcr = TryStaticPointerDowncast(Self, SrcType, DestType, CStyle, OpRange, msg,1501 Kind, BasePath);1502 if (tcr != TC_NotApplicable)1503 return tcr;1504 1505 // Reverse member pointer conversion. C++ 4.11 specifies member pointer1506 // conversion. C++ 5.2.9p9 has additional information.1507 // DR54's access restrictions apply here also.1508 tcr = TryStaticMemberPointerUpcast(Self, SrcExpr, SrcType, DestType, CStyle,1509 OpRange, msg, Kind, BasePath);1510 if (tcr != TC_NotApplicable)1511 return tcr;1512 1513 // Reverse pointer conversion to void*. C++ 4.10.p2 specifies conversion to1514 // void*. C++ 5.2.9p10 specifies additional restrictions, which really is1515 // just the usual constness stuff.1516 if (const PointerType *SrcPointer = SrcType->getAs<PointerType>()) {1517 QualType SrcPointee = SrcPointer->getPointeeType();1518 if (SrcPointee->isVoidType()) {1519 if (const PointerType *DestPointer = DestType->getAs<PointerType>()) {1520 QualType DestPointee = DestPointer->getPointeeType();1521 if (DestPointee->isIncompleteOrObjectType()) {1522 // This is definitely the intended conversion, but it might fail due1523 // to a qualifier violation. Note that we permit Objective-C lifetime1524 // and GC qualifier mismatches here.1525 if (!CStyle) {1526 Qualifiers DestPointeeQuals = DestPointee.getQualifiers();1527 Qualifiers SrcPointeeQuals = SrcPointee.getQualifiers();1528 DestPointeeQuals.removeObjCGCAttr();1529 DestPointeeQuals.removeObjCLifetime();1530 SrcPointeeQuals.removeObjCGCAttr();1531 SrcPointeeQuals.removeObjCLifetime();1532 if (DestPointeeQuals != SrcPointeeQuals &&1533 !DestPointeeQuals.compatiblyIncludes(SrcPointeeQuals,1534 Self.getASTContext())) {1535 msg = diag::err_bad_cxx_cast_qualifiers_away;1536 return TC_Failed;1537 }1538 }1539 Kind = IsAddressSpaceConversion(SrcType, DestType)1540 ? CK_AddressSpaceConversion1541 : CK_BitCast;1542 return TC_Success;1543 }1544 1545 // Microsoft permits static_cast from 'pointer-to-void' to1546 // 'pointer-to-function'.1547 if (!CStyle && Self.getLangOpts().MSVCCompat &&1548 DestPointee->isFunctionType()) {1549 Self.Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange;1550 Kind = CK_BitCast;1551 return TC_Success;1552 }1553 }1554 else if (DestType->isObjCObjectPointerType()) {1555 // allow both c-style cast and static_cast of objective-c pointers as1556 // they are pervasive.1557 Kind = CK_CPointerToObjCPointerCast;1558 return TC_Success;1559 }1560 else if (CStyle && DestType->isBlockPointerType()) {1561 // allow c-style cast of void * to block pointers.1562 Kind = CK_AnyPointerToBlockPointerCast;1563 return TC_Success;1564 }1565 }1566 }1567 // Allow arbitrary objective-c pointer conversion with static casts.1568 if (SrcType->isObjCObjectPointerType() &&1569 DestType->isObjCObjectPointerType()) {1570 Kind = CK_BitCast;1571 return TC_Success;1572 }1573 // Allow ns-pointer to cf-pointer conversion in either direction1574 // with static casts.1575 if (!CStyle &&1576 Self.ObjC().CheckTollFreeBridgeStaticCast(DestType, SrcExpr.get(), Kind))1577 return TC_Success;1578 1579 // See if it looks like the user is trying to convert between1580 // related record types, and select a better diagnostic if so.1581 if (const auto *SrcPointer = SrcType->getAs<PointerType>())1582 if (const auto *DestPointer = DestType->getAs<PointerType>())1583 if (SrcPointer->getPointeeType()->isRecordType() &&1584 DestPointer->getPointeeType()->isRecordType())1585 msg = diag::err_bad_cxx_cast_unrelated_class;1586 1587 if (SrcType->isMatrixType() && DestType->isMatrixType()) {1588 if (Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind)) {1589 SrcExpr = ExprError();1590 return TC_Failed;1591 }1592 return TC_Success;1593 }1594 1595 // We tried everything. Everything! Nothing works! :-(1596 return TC_NotApplicable;1597}1598 1599/// Tests whether a conversion according to N2844 is valid.1600TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr,1601 QualType DestType, bool CStyle,1602 SourceRange OpRange, CastKind &Kind,1603 CXXCastPath &BasePath, unsigned &msg) {1604 // C++11 [expr.static.cast]p3:1605 // A glvalue of type "cv1 T1" can be cast to type "rvalue reference to1606 // cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".1607 const RValueReferenceType *R = DestType->getAs<RValueReferenceType>();1608 if (!R)1609 return TC_NotApplicable;1610 1611 if (!SrcExpr->isGLValue())1612 return TC_NotApplicable;1613 1614 // Because we try the reference downcast before this function, from now on1615 // this is the only cast possibility, so we issue an error if we fail now.1616 QualType FromType = SrcExpr->getType();1617 QualType ToType = R->getPointeeType();1618 if (CStyle) {1619 FromType = FromType.getUnqualifiedType();1620 ToType = ToType.getUnqualifiedType();1621 }1622 1623 Sema::ReferenceConversions RefConv;1624 Sema::ReferenceCompareResult RefResult = Self.CompareReferenceRelationship(1625 SrcExpr->getBeginLoc(), ToType, FromType, &RefConv);1626 if (RefResult != Sema::Ref_Compatible) {1627 if (CStyle || RefResult == Sema::Ref_Incompatible)1628 return TC_NotApplicable;1629 // Diagnose types which are reference-related but not compatible here since1630 // we can provide better diagnostics. In these cases forwarding to1631 // [expr.static.cast]p4 should never result in a well-formed cast.1632 msg = SrcExpr->isLValue() ? diag::err_bad_lvalue_to_rvalue_cast1633 : diag::err_bad_rvalue_to_rvalue_cast;1634 return TC_Failed;1635 }1636 1637 if (RefConv & Sema::ReferenceConversions::DerivedToBase) {1638 Kind = CK_DerivedToBase;1639 if (Self.CheckDerivedToBaseConversion(FromType, ToType,1640 SrcExpr->getBeginLoc(), OpRange,1641 &BasePath, CStyle)) {1642 msg = 0;1643 return TC_Failed;1644 }1645 } else1646 Kind = CK_NoOp;1647 1648 return TC_Success;1649}1650 1651/// Tests whether a conversion according to C++ 5.2.9p5 is valid.1652TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr,1653 QualType DestType, bool CStyle,1654 CastOperation::OpRangeType OpRange,1655 unsigned &msg, CastKind &Kind,1656 CXXCastPath &BasePath) {1657 // C++ 5.2.9p5: An lvalue of type "cv1 B", where B is a class type, can be1658 // cast to type "reference to cv2 D", where D is a class derived from B,1659 // if a valid standard conversion from "pointer to D" to "pointer to B"1660 // exists, cv2 >= cv1, and B is not a virtual base class of D.1661 // In addition, DR54 clarifies that the base must be accessible in the1662 // current context. Although the wording of DR54 only applies to the pointer1663 // variant of this rule, the intent is clearly for it to apply to the this1664 // conversion as well.1665 1666 const ReferenceType *DestReference = DestType->getAs<ReferenceType>();1667 if (!DestReference) {1668 return TC_NotApplicable;1669 }1670 bool RValueRef = DestReference->isRValueReferenceType();1671 if (!RValueRef && !SrcExpr->isLValue()) {1672 // We know the left side is an lvalue reference, so we can suggest a reason.1673 msg = diag::err_bad_cxx_cast_rvalue;1674 return TC_NotApplicable;1675 }1676 1677 QualType DestPointee = DestReference->getPointeeType();1678 1679 // FIXME: If the source is a prvalue, we should issue a warning (because the1680 // cast always has undefined behavior), and for AST consistency, we should1681 // materialize a temporary.1682 return TryStaticDowncast(Self,1683 Self.Context.getCanonicalType(SrcExpr->getType()),1684 Self.Context.getCanonicalType(DestPointee), CStyle,1685 OpRange, SrcExpr->getType(), DestType, msg, Kind,1686 BasePath);1687}1688 1689/// Tests whether a conversion according to C++ 5.2.9p8 is valid.1690TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType,1691 QualType DestType, bool CStyle,1692 CastOperation::OpRangeType OpRange,1693 unsigned &msg, CastKind &Kind,1694 CXXCastPath &BasePath) {1695 // C++ 5.2.9p8: An rvalue of type "pointer to cv1 B", where B is a class1696 // type, can be converted to an rvalue of type "pointer to cv2 D", where D1697 // is a class derived from B, if a valid standard conversion from "pointer1698 // to D" to "pointer to B" exists, cv2 >= cv1, and B is not a virtual base1699 // class of D.1700 // In addition, DR54 clarifies that the base must be accessible in the1701 // current context.1702 1703 const PointerType *DestPointer = DestType->getAs<PointerType>();1704 if (!DestPointer) {1705 return TC_NotApplicable;1706 }1707 1708 const PointerType *SrcPointer = SrcType->getAs<PointerType>();1709 if (!SrcPointer) {1710 msg = diag::err_bad_static_cast_pointer_nonpointer;1711 return TC_NotApplicable;1712 }1713 1714 return TryStaticDowncast(Self,1715 Self.Context.getCanonicalType(SrcPointer->getPointeeType()),1716 Self.Context.getCanonicalType(DestPointer->getPointeeType()),1717 CStyle, OpRange, SrcType, DestType, msg, Kind,1718 BasePath);1719}1720 1721/// TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and1722/// TryStaticPointerDowncast. Tests whether a static downcast from SrcType to1723/// DestType is possible and allowed.1724TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,1725 CanQualType DestType, bool CStyle,1726 CastOperation::OpRangeType OpRange,1727 QualType OrigSrcType, QualType OrigDestType,1728 unsigned &msg, CastKind &Kind,1729 CXXCastPath &BasePath) {1730 // We can only work with complete types. But don't complain if it doesn't work1731 if (!Self.isCompleteType(OpRange.getBegin(), SrcType) ||1732 !Self.isCompleteType(OpRange.getBegin(), DestType))1733 return TC_NotApplicable;1734 1735 // Downcast can only happen in class hierarchies, so we need classes.1736 if (!DestType->getAs<RecordType>() || !SrcType->getAs<RecordType>()) {1737 return TC_NotApplicable;1738 }1739 1740 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,1741 /*DetectVirtual=*/true);1742 if (!Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths)) {1743 return TC_NotApplicable;1744 }1745 1746 // Target type does derive from source type. Now we're serious. If an error1747 // appears now, it's not ignored.1748 // This may not be entirely in line with the standard. Take for example:1749 // struct A {};1750 // struct B : virtual A {1751 // B(A&);1752 // };1753 //1754 // void f()1755 // {1756 // (void)static_cast<const B&>(*((A*)0));1757 // }1758 // As far as the standard is concerned, p5 does not apply (A is virtual), so1759 // p2 should be used instead - "const B& t(*((A*)0));" is perfectly valid.1760 // However, both GCC and Comeau reject this example, and accepting it would1761 // mean more complex code if we're to preserve the nice error message.1762 // FIXME: Being 100% compliant here would be nice to have.1763 1764 // Must preserve cv, as always, unless we're in C-style mode.1765 if (!CStyle &&1766 !DestType.isAtLeastAsQualifiedAs(SrcType, Self.getASTContext())) {1767 msg = diag::err_bad_cxx_cast_qualifiers_away;1768 return TC_Failed;1769 }1770 1771 if (Paths.isAmbiguous(SrcType.getUnqualifiedType())) {1772 // This code is analoguous to that in CheckDerivedToBaseConversion, except1773 // that it builds the paths in reverse order.1774 // To sum up: record all paths to the base and build a nice string from1775 // them. Use it to spice up the error message.1776 if (!Paths.isRecordingPaths()) {1777 Paths.clear();1778 Paths.setRecordingPaths(true);1779 Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths);1780 }1781 std::string PathDisplayStr;1782 std::set<unsigned> DisplayedPaths;1783 for (clang::CXXBasePath &Path : Paths) {1784 if (DisplayedPaths.insert(Path.back().SubobjectNumber).second) {1785 // We haven't displayed a path to this particular base1786 // class subobject yet.1787 PathDisplayStr += "\n ";1788 for (CXXBasePathElement &PE : llvm::reverse(Path))1789 PathDisplayStr += PE.Base->getType().getAsString() + " -> ";1790 PathDisplayStr += QualType(DestType).getAsString();1791 }1792 }1793 1794 Self.Diag(OpRange.getBegin(), diag::err_ambiguous_base_to_derived_cast)1795 << QualType(SrcType).getUnqualifiedType()1796 << QualType(DestType).getUnqualifiedType()1797 << PathDisplayStr << OpRange;1798 msg = 0;1799 return TC_Failed;1800 }1801 1802 if (Paths.getDetectedVirtual() != nullptr) {1803 QualType VirtualBase(Paths.getDetectedVirtual(), 0);1804 Self.Diag(OpRange.getBegin(), diag::err_static_downcast_via_virtual)1805 << OrigSrcType << OrigDestType << VirtualBase << OpRange;1806 msg = 0;1807 return TC_Failed;1808 }1809 1810 if (!CStyle) {1811 switch (Self.CheckBaseClassAccess(OpRange.getBegin(),1812 SrcType, DestType,1813 Paths.front(),1814 diag::err_downcast_from_inaccessible_base)) {1815 case Sema::AR_accessible:1816 case Sema::AR_delayed: // be optimistic1817 case Sema::AR_dependent: // be optimistic1818 break;1819 1820 case Sema::AR_inaccessible:1821 msg = 0;1822 return TC_Failed;1823 }1824 }1825 1826 Self.BuildBasePathArray(Paths, BasePath);1827 Kind = CK_BaseToDerived;1828 return TC_Success;1829}1830 1831/// TryStaticMemberPointerUpcast - Tests whether a conversion according to1832/// C++ 5.2.9p9 is valid:1833///1834/// An rvalue of type "pointer to member of D of type cv1 T" can be1835/// converted to an rvalue of type "pointer to member of B of type cv2 T",1836/// where B is a base class of D [...].1837///1838TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr,1839 QualType SrcType, QualType DestType,1840 bool CStyle,1841 CastOperation::OpRangeType OpRange,1842 unsigned &msg, CastKind &Kind,1843 CXXCastPath &BasePath) {1844 const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>();1845 if (!DestMemPtr)1846 return TC_NotApplicable;1847 1848 bool WasOverloadedFunction = false;1849 DeclAccessPair FoundOverload;1850 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {1851 if (FunctionDecl *Fn1852 = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), DestType, false,1853 FoundOverload)) {1854 CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);1855 SrcType = Self.Context.getMemberPointerType(1856 Fn->getType(), /*Qualifier=*/std::nullopt, M->getParent());1857 WasOverloadedFunction = true;1858 }1859 }1860 1861 switch (Self.CheckMemberPointerConversion(1862 SrcType, DestMemPtr, Kind, BasePath, OpRange.getBegin(), OpRange, CStyle,1863 Sema::MemberPointerConversionDirection::Upcast)) {1864 case Sema::MemberPointerConversionResult::Success:1865 if (Kind == CK_NullToMemberPointer) {1866 msg = diag::err_bad_static_cast_member_pointer_nonmp;1867 return TC_NotApplicable;1868 }1869 break;1870 case Sema::MemberPointerConversionResult::DifferentPointee:1871 case Sema::MemberPointerConversionResult::NotDerived:1872 return TC_NotApplicable;1873 case Sema::MemberPointerConversionResult::Ambiguous:1874 case Sema::MemberPointerConversionResult::Virtual:1875 case Sema::MemberPointerConversionResult::Inaccessible:1876 msg = 0;1877 return TC_Failed;1878 }1879 1880 if (WasOverloadedFunction) {1881 // Resolve the address of the overloaded function again, this time1882 // allowing complaints if something goes wrong.1883 FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),1884 DestType,1885 true,1886 FoundOverload);1887 if (!Fn) {1888 msg = 0;1889 return TC_Failed;1890 }1891 1892 SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn);1893 if (!SrcExpr.isUsable()) {1894 msg = 0;1895 return TC_Failed;1896 }1897 }1898 return TC_Success;1899}1900 1901/// TryStaticImplicitCast - Tests whether a conversion according to C++ 5.2.9p21902/// is valid:1903///1904/// An expression e can be explicitly converted to a type T using a1905/// @c static_cast if the declaration "T t(e);" is well-formed [...].1906TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr,1907 QualType DestType,1908 CheckedConversionKind CCK,1909 CastOperation::OpRangeType OpRange,1910 unsigned &msg, CastKind &Kind,1911 bool ListInitialization) {1912 if (DestType->isRecordType()) {1913 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,1914 diag::err_bad_cast_incomplete) ||1915 Self.RequireNonAbstractType(OpRange.getBegin(), DestType,1916 diag::err_allocation_of_abstract_type)) {1917 msg = 0;1918 return TC_Failed;1919 }1920 }1921 1922 InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);1923 InitializationKind InitKind =1924 (CCK == CheckedConversionKind::CStyleCast)1925 ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange,1926 ListInitialization)1927 : (CCK == CheckedConversionKind::FunctionalCast)1928 ? InitializationKind::CreateFunctionalCast(1929 OpRange.getBegin(), OpRange.getParenRange(), ListInitialization)1930 : InitializationKind::CreateCast(OpRange);1931 Expr *SrcExprRaw = SrcExpr.get();1932 // FIXME: Per DR242, we should check for an implicit conversion sequence1933 // or for a constructor that could be invoked by direct-initialization1934 // here, not for an initialization sequence.1935 InitializationSequence InitSeq(Self, Entity, InitKind, SrcExprRaw);1936 1937 // At this point of CheckStaticCast, if the destination is a reference,1938 // or the expression is an overload expression this has to work.1939 // There is no other way that works.1940 // On the other hand, if we're checking a C-style cast, we've still got1941 // the reinterpret_cast way.1942 bool CStyle = (CCK == CheckedConversionKind::CStyleCast ||1943 CCK == CheckedConversionKind::FunctionalCast);1944 if (InitSeq.Failed() && (CStyle || !DestType->isReferenceType()))1945 return TC_NotApplicable;1946 1947 ExprResult Result = InitSeq.Perform(Self, Entity, InitKind, SrcExprRaw);1948 if (Result.isInvalid()) {1949 msg = 0;1950 return TC_Failed;1951 }1952 1953 if (InitSeq.isConstructorInitialization())1954 Kind = CK_ConstructorConversion;1955 else1956 Kind = CK_NoOp;1957 1958 SrcExpr = Result;1959 return TC_Success;1960}1961 1962/// TryConstCast - See if a const_cast from source to destination is allowed,1963/// and perform it if it is.1964static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr,1965 QualType DestType, bool CStyle,1966 unsigned &msg) {1967 DestType = Self.Context.getCanonicalType(DestType);1968 QualType SrcType = SrcExpr.get()->getType();1969 bool NeedToMaterializeTemporary = false;1970 1971 if (const ReferenceType *DestTypeTmp =DestType->getAs<ReferenceType>()) {1972 // C++11 5.2.11p4:1973 // if a pointer to T1 can be explicitly converted to the type "pointer to1974 // T2" using a const_cast, then the following conversions can also be1975 // made:1976 // -- an lvalue of type T1 can be explicitly converted to an lvalue of1977 // type T2 using the cast const_cast<T2&>;1978 // -- a glvalue of type T1 can be explicitly converted to an xvalue of1979 // type T2 using the cast const_cast<T2&&>; and1980 // -- if T1 is a class type, a prvalue of type T1 can be explicitly1981 // converted to an xvalue of type T2 using the cast const_cast<T2&&>.1982 1983 if (isa<LValueReferenceType>(DestTypeTmp) && !SrcExpr.get()->isLValue()) {1984 // Cannot const_cast non-lvalue to lvalue reference type. But if this1985 // is C-style, static_cast might find a way, so we simply suggest a1986 // message and tell the parent to keep searching.1987 msg = diag::err_bad_cxx_cast_rvalue;1988 return TC_NotApplicable;1989 }1990 1991 if (isa<RValueReferenceType>(DestTypeTmp) && SrcExpr.get()->isPRValue()) {1992 if (!SrcType->isRecordType()) {1993 // Cannot const_cast non-class prvalue to rvalue reference type. But if1994 // this is C-style, static_cast can do this.1995 msg = diag::err_bad_cxx_cast_rvalue;1996 return TC_NotApplicable;1997 }1998 1999 // Materialize the class prvalue so that the const_cast can bind a2000 // reference to it.2001 NeedToMaterializeTemporary = true;2002 }2003 2004 // It's not completely clear under the standard whether we can2005 // const_cast bit-field gl-values. Doing so would not be2006 // intrinsically complicated, but for now, we say no for2007 // consistency with other compilers and await the word of the2008 // committee.2009 if (SrcExpr.get()->refersToBitField()) {2010 msg = diag::err_bad_cxx_cast_bitfield;2011 return TC_NotApplicable;2012 }2013 2014 DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());2015 SrcType = Self.Context.getPointerType(SrcType);2016 }2017 2018 // C++ 5.2.11p5: For a const_cast involving pointers to data members [...]2019 // the rules for const_cast are the same as those used for pointers.2020 2021 if (!DestType->isPointerType() &&2022 !DestType->isMemberPointerType() &&2023 !DestType->isObjCObjectPointerType()) {2024 // Cannot cast to non-pointer, non-reference type. Note that, if DestType2025 // was a reference type, we converted it to a pointer above.2026 // The status of rvalue references isn't entirely clear, but it looks like2027 // conversion to them is simply invalid.2028 // C++ 5.2.11p3: For two pointer types [...]2029 if (!CStyle)2030 msg = diag::err_bad_const_cast_dest;2031 return TC_NotApplicable;2032 }2033 if (DestType->isFunctionPointerType() ||2034 DestType->isMemberFunctionPointerType()) {2035 // Cannot cast direct function pointers.2036 // C++ 5.2.11p2: [...] where T is any object type or the void type [...]2037 // T is the ultimate pointee of source and target type.2038 if (!CStyle)2039 msg = diag::err_bad_const_cast_dest;2040 return TC_NotApplicable;2041 }2042 2043 // C++ [expr.const.cast]p3:2044 // "For two similar types T1 and T2, [...]"2045 //2046 // We only allow a const_cast to change cvr-qualifiers, not other kinds of2047 // type qualifiers. (Likewise, we ignore other changes when determining2048 // whether a cast casts away constness.)2049 if (!Self.Context.hasCvrSimilarType(SrcType, DestType))2050 return TC_NotApplicable;2051 2052 if (NeedToMaterializeTemporary)2053 // This is a const_cast from a class prvalue to an rvalue reference type.2054 // Materialize a temporary to store the result of the conversion.2055 SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcExpr.get()->getType(),2056 SrcExpr.get(),2057 /*IsLValueReference*/ false);2058 2059 return TC_Success;2060}2061 2062// Checks for undefined behavior in reinterpret_cast.2063// The cases that is checked for is:2064// *reinterpret_cast<T*>(&a)2065// reinterpret_cast<T&>(a)2066// where accessing 'a' as type 'T' will result in undefined behavior.2067void Sema::CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,2068 bool IsDereference,2069 SourceRange Range) {2070 unsigned DiagID = IsDereference ?2071 diag::warn_pointer_indirection_from_incompatible_type :2072 diag::warn_undefined_reinterpret_cast;2073 2074 if (Diags.isIgnored(DiagID, Range.getBegin()))2075 return;2076 2077 QualType SrcTy, DestTy;2078 if (IsDereference) {2079 if (!SrcType->getAs<PointerType>() || !DestType->getAs<PointerType>()) {2080 return;2081 }2082 SrcTy = SrcType->getPointeeType();2083 DestTy = DestType->getPointeeType();2084 } else {2085 if (!DestType->getAs<ReferenceType>()) {2086 return;2087 }2088 SrcTy = SrcType;2089 DestTy = DestType->getPointeeType();2090 }2091 2092 // Cast is compatible if the types are the same.2093 if (Context.hasSameUnqualifiedType(DestTy, SrcTy)) {2094 return;2095 }2096 // or one of the types is a char or void type2097 if (DestTy->isAnyCharacterType() || DestTy->isVoidType() ||2098 SrcTy->isAnyCharacterType() || SrcTy->isVoidType()) {2099 return;2100 }2101 // or one of the types is a tag type.2102 if (isa<TagType>(SrcTy.getCanonicalType()) ||2103 isa<TagType>(DestTy.getCanonicalType()))2104 return;2105 2106 // FIXME: Scoped enums?2107 if ((SrcTy->isUnsignedIntegerType() && DestTy->isSignedIntegerType()) ||2108 (SrcTy->isSignedIntegerType() && DestTy->isUnsignedIntegerType())) {2109 if (Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy)) {2110 return;2111 }2112 }2113 2114 if (SrcTy->isDependentType() || DestTy->isDependentType()) {2115 return;2116 }2117 2118 Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range;2119}2120 2121static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr,2122 QualType DestType) {2123 QualType SrcType = SrcExpr.get()->getType();2124 if (Self.Context.hasSameType(SrcType, DestType))2125 return;2126 if (const PointerType *SrcPtrTy = SrcType->getAs<PointerType>())2127 if (SrcPtrTy->isObjCSelType()) {2128 QualType DT = DestType;2129 if (isa<PointerType>(DestType))2130 DT = DestType->getPointeeType();2131 if (!DT.getUnqualifiedType()->isVoidType())2132 Self.Diag(SrcExpr.get()->getExprLoc(),2133 diag::warn_cast_pointer_from_sel)2134 << SrcType << DestType << SrcExpr.get()->getSourceRange();2135 }2136}2137 2138/// Diagnose casts that change the calling convention of a pointer to a function2139/// defined in the current TU.2140static void DiagnoseCallingConvCast(Sema &Self, const ExprResult &SrcExpr,2141 QualType DstType,2142 CastOperation::OpRangeType OpRange) {2143 // Check if this cast would change the calling convention of a function2144 // pointer type.2145 QualType SrcType = SrcExpr.get()->getType();2146 if (Self.Context.hasSameType(SrcType, DstType) ||2147 !SrcType->isFunctionPointerType() || !DstType->isFunctionPointerType())2148 return;2149 const auto *SrcFTy =2150 SrcType->castAs<PointerType>()->getPointeeType()->castAs<FunctionType>();2151 const auto *DstFTy =2152 DstType->castAs<PointerType>()->getPointeeType()->castAs<FunctionType>();2153 CallingConv SrcCC = SrcFTy->getCallConv();2154 CallingConv DstCC = DstFTy->getCallConv();2155 if (SrcCC == DstCC)2156 return;2157 2158 // We have a calling convention cast. Check if the source is a pointer to a2159 // known, specific function that has already been defined.2160 Expr *Src = SrcExpr.get()->IgnoreParenImpCasts();2161 if (auto *UO = dyn_cast<UnaryOperator>(Src))2162 if (UO->getOpcode() == UO_AddrOf)2163 Src = UO->getSubExpr()->IgnoreParenImpCasts();2164 auto *DRE = dyn_cast<DeclRefExpr>(Src);2165 if (!DRE)2166 return;2167 auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl());2168 if (!FD)2169 return;2170 2171 // Only warn if we are casting from the default convention to a non-default2172 // convention. This can happen when the programmer forgot to apply the calling2173 // convention to the function declaration and then inserted this cast to2174 // satisfy the type system.2175 CallingConv DefaultCC = Self.getASTContext().getDefaultCallingConvention(2176 FD->isVariadic(), FD->isCXXInstanceMember());2177 if (DstCC == DefaultCC || SrcCC != DefaultCC)2178 return;2179 2180 // Diagnose this cast, as it is probably bad.2181 StringRef SrcCCName = FunctionType::getNameForCallConv(SrcCC);2182 StringRef DstCCName = FunctionType::getNameForCallConv(DstCC);2183 Self.Diag(OpRange.getBegin(), diag::warn_cast_calling_conv)2184 << SrcCCName << DstCCName << OpRange;2185 2186 // The checks above are cheaper than checking if the diagnostic is enabled.2187 // However, it's worth checking if the warning is enabled before we construct2188 // a fixit.2189 if (Self.Diags.isIgnored(diag::warn_cast_calling_conv, OpRange.getBegin()))2190 return;2191 2192 // Try to suggest a fixit to change the calling convention of the function2193 // whose address was taken. Try to use the latest macro for the convention.2194 // For example, users probably want to write "WINAPI" instead of "__stdcall"2195 // to match the Windows header declarations.2196 SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc();2197 Preprocessor &PP = Self.getPreprocessor();2198 SmallVector<TokenValue, 6> AttrTokens;2199 SmallString<64> CCAttrText;2200 llvm::raw_svector_ostream OS(CCAttrText);2201 if (Self.getLangOpts().MicrosoftExt) {2202 // __stdcall or __vectorcall2203 OS << "__" << DstCCName;2204 IdentifierInfo *II = PP.getIdentifierInfo(OS.str());2205 AttrTokens.push_back(II->isKeyword(Self.getLangOpts())2206 ? TokenValue(II->getTokenID())2207 : TokenValue(II));2208 } else {2209 // __attribute__((stdcall)) or __attribute__((vectorcall))2210 OS << "__attribute__((" << DstCCName << "))";2211 AttrTokens.push_back(tok::kw___attribute);2212 AttrTokens.push_back(tok::l_paren);2213 AttrTokens.push_back(tok::l_paren);2214 IdentifierInfo *II = PP.getIdentifierInfo(DstCCName);2215 AttrTokens.push_back(II->isKeyword(Self.getLangOpts())2216 ? TokenValue(II->getTokenID())2217 : TokenValue(II));2218 AttrTokens.push_back(tok::r_paren);2219 AttrTokens.push_back(tok::r_paren);2220 }2221 StringRef AttrSpelling = PP.getLastMacroWithSpelling(NameLoc, AttrTokens);2222 if (!AttrSpelling.empty())2223 CCAttrText = AttrSpelling;2224 OS << ' ';2225 Self.Diag(NameLoc, diag::note_change_calling_conv_fixit)2226 << FD << DstCCName << FixItHint::CreateInsertion(NameLoc, CCAttrText);2227}2228 2229static void checkIntToPointerCast(bool CStyle, const SourceRange &OpRange,2230 const Expr *SrcExpr, QualType DestType,2231 Sema &Self) {2232 QualType SrcType = SrcExpr->getType();2233 2234 // Not warning on reinterpret_cast, boolean, constant expressions, etc2235 // are not explicit design choices, but consistent with GCC's behavior.2236 // Feel free to modify them if you've reason/evidence for an alternative.2237 if (CStyle && SrcType->isIntegralType(Self.Context)2238 && !SrcType->isBooleanType()2239 && !SrcType->isEnumeralType()2240 && !SrcExpr->isIntegerConstantExpr(Self.Context)2241 && Self.Context.getTypeSize(DestType) >2242 Self.Context.getTypeSize(SrcType)) {2243 // Separate between casts to void* and non-void* pointers.2244 // Some APIs use (abuse) void* for something like a user context,2245 // and often that value is an integer even if it isn't a pointer itself.2246 // Having a separate warning flag allows users to control the warning2247 // for their workflow.2248 unsigned Diag = DestType->isVoidPointerType() ?2249 diag::warn_int_to_void_pointer_cast2250 : diag::warn_int_to_pointer_cast;2251 Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;2252 }2253}2254 2255static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType,2256 ExprResult &Result) {2257 // We can only fix an overloaded reinterpret_cast if2258 // - it is a template with explicit arguments that resolves to an lvalue2259 // unambiguously, or2260 // - it is the only function in an overload set that may have its address2261 // taken.2262 2263 Expr *E = Result.get();2264 // TODO: what if this fails because of DiagnoseUseOfDecl or something2265 // like it?2266 if (Self.ResolveAndFixSingleFunctionTemplateSpecialization(2267 Result,2268 Expr::getValueKindForType(DestType) ==2269 VK_PRValue // Convert Fun to Ptr2270 ) &&2271 Result.isUsable())2272 return true;2273 2274 // No guarantees that ResolveAndFixSingleFunctionTemplateSpecialization2275 // preserves Result.2276 Result = E;2277 if (!Self.resolveAndFixAddressOfSingleOverloadCandidate(2278 Result, /*DoFunctionPointerConversion=*/true))2279 return false;2280 return Result.isUsable();2281}2282 2283static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,2284 QualType DestType, bool CStyle,2285 CastOperation::OpRangeType OpRange,2286 unsigned &msg, CastKind &Kind) {2287 bool IsLValueCast = false;2288 2289 DestType = Self.Context.getCanonicalType(DestType);2290 QualType SrcType = SrcExpr.get()->getType();2291 2292 // Is the source an overloaded name? (i.e. &foo)2293 // If so, reinterpret_cast generally can not help us here (13.4, p1, bullet 5)2294 if (SrcType == Self.Context.OverloadTy) {2295 ExprResult FixedExpr = SrcExpr;2296 if (!fixOverloadedReinterpretCastExpr(Self, DestType, FixedExpr))2297 return TC_NotApplicable;2298 2299 assert(FixedExpr.isUsable() && "Invalid result fixing overloaded expr");2300 SrcExpr = FixedExpr;2301 SrcType = SrcExpr.get()->getType();2302 }2303 2304 if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {2305 if (!SrcExpr.get()->isGLValue()) {2306 // Cannot cast non-glvalue to (lvalue or rvalue) reference type. See the2307 // similar comment in const_cast.2308 msg = diag::err_bad_cxx_cast_rvalue;2309 return TC_NotApplicable;2310 }2311 2312 if (!CStyle) {2313 Self.CheckCompatibleReinterpretCast(SrcType, DestType,2314 /*IsDereference=*/false, OpRange);2315 }2316 2317 // C++ 5.2.10p10: [...] a reference cast reinterpret_cast<T&>(x) has the2318 // same effect as the conversion *reinterpret_cast<T*>(&x) with the2319 // built-in & and * operators.2320 2321 const char *inappropriate = nullptr;2322 switch (SrcExpr.get()->getObjectKind()) {2323 case OK_Ordinary:2324 break;2325 case OK_BitField:2326 msg = diag::err_bad_cxx_cast_bitfield;2327 return TC_NotApplicable;2328 // FIXME: Use a specific diagnostic for the rest of these cases.2329 case OK_VectorComponent: inappropriate = "vector element"; break;2330 case OK_MatrixComponent:2331 inappropriate = "matrix element";2332 break;2333 case OK_ObjCProperty: inappropriate = "property expression"; break;2334 case OK_ObjCSubscript: inappropriate = "container subscripting expression";2335 break;2336 }2337 if (inappropriate) {2338 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_reference)2339 << inappropriate << DestType2340 << OpRange << SrcExpr.get()->getSourceRange();2341 msg = 0; SrcExpr = ExprError();2342 return TC_NotApplicable;2343 }2344 2345 // This code does this transformation for the checked types.2346 DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());2347 SrcType = Self.Context.getPointerType(SrcType);2348 2349 IsLValueCast = true;2350 }2351 2352 // Canonicalize source for comparison.2353 SrcType = Self.Context.getCanonicalType(SrcType);2354 2355 const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>(),2356 *SrcMemPtr = SrcType->getAs<MemberPointerType>();2357 if (DestMemPtr && SrcMemPtr) {2358 // C++ 5.2.10p9: An rvalue of type "pointer to member of X of type T1"2359 // can be explicitly converted to an rvalue of type "pointer to member2360 // of Y of type T2" if T1 and T2 are both function types or both object2361 // types.2362 if (DestMemPtr->isMemberFunctionPointer() !=2363 SrcMemPtr->isMemberFunctionPointer())2364 return TC_NotApplicable;2365 2366 if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {2367 // We need to determine the inheritance model that the class will use if2368 // haven't yet.2369 (void)Self.isCompleteType(OpRange.getBegin(), SrcType);2370 (void)Self.isCompleteType(OpRange.getBegin(), DestType);2371 }2372 2373 // Don't allow casting between member pointers of different sizes.2374 if (Self.Context.getTypeSize(DestMemPtr) !=2375 Self.Context.getTypeSize(SrcMemPtr)) {2376 msg = diag::err_bad_cxx_cast_member_pointer_size;2377 return TC_Failed;2378 }2379 2380 // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away2381 // constness.2382 // A reinterpret_cast followed by a const_cast can, though, so in C-style,2383 // we accept it.2384 if (auto CACK =2385 CastsAwayConstness(Self, SrcType, DestType, /*CheckCVR=*/!CStyle,2386 /*CheckObjCLifetime=*/CStyle))2387 return getCastAwayConstnessCastKind(CACK, msg);2388 2389 // A valid member pointer cast.2390 assert(!IsLValueCast);2391 Kind = CK_ReinterpretMemberPointer;2392 return TC_Success;2393 }2394 2395 // See below for the enumeral issue.2396 if (SrcType->isNullPtrType() && DestType->isIntegralType(Self.Context)) {2397 // C++0x 5.2.10p4: A pointer can be explicitly converted to any integral2398 // type large enough to hold it. A value of std::nullptr_t can be2399 // converted to an integral type; the conversion has the same meaning2400 // and validity as a conversion of (void*)0 to the integral type.2401 if (Self.Context.getTypeSize(SrcType) >2402 Self.Context.getTypeSize(DestType)) {2403 msg = diag::err_bad_reinterpret_cast_small_int;2404 return TC_Failed;2405 }2406 Kind = CK_PointerToIntegral;2407 return TC_Success;2408 }2409 2410 // Allow reinterpret_casts between vectors of the same size and2411 // between vectors and integers of the same size.2412 bool destIsVector = DestType->isVectorType();2413 bool srcIsVector = SrcType->isVectorType();2414 if (srcIsVector || destIsVector) {2415 // Allow bitcasting between SVE VLATs and VLSTs, and vice-versa.2416 if (Self.isValidSveBitcast(SrcType, DestType)) {2417 Kind = CK_BitCast;2418 return TC_Success;2419 }2420 2421 // Allow bitcasting between SVE VLATs and VLSTs, and vice-versa.2422 if (Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {2423 Kind = CK_BitCast;2424 return TC_Success;2425 }2426 2427 // The non-vector type, if any, must have integral type. This is2428 // the same rule that C vector casts use; note, however, that enum2429 // types are not integral in C++.2430 if ((!destIsVector && !DestType->isIntegralType(Self.Context)) ||2431 (!srcIsVector && !SrcType->isIntegralType(Self.Context)))2432 return TC_NotApplicable;2433 2434 // The size we want to consider is eltCount * eltSize.2435 // That's exactly what the lax-conversion rules will check.2436 if (Self.areLaxCompatibleVectorTypes(SrcType, DestType)) {2437 Kind = CK_BitCast;2438 return TC_Success;2439 }2440 2441 if (Self.LangOpts.OpenCL && !CStyle) {2442 if (DestType->isExtVectorType() || SrcType->isExtVectorType()) {2443 // FIXME: Allow for reinterpret cast between 3 and 4 element vectors2444 if (Self.areVectorTypesSameSize(SrcType, DestType)) {2445 Kind = CK_BitCast;2446 return TC_Success;2447 }2448 }2449 }2450 2451 // Otherwise, pick a reasonable diagnostic.2452 if (!destIsVector)2453 msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;2454 else if (!srcIsVector)2455 msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;2456 else2457 msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;2458 2459 return TC_Failed;2460 }2461 2462 if (SrcType == DestType) {2463 // C++ 5.2.10p2 has a note that mentions that, subject to all other2464 // restrictions, a cast to the same type is allowed so long as it does not2465 // cast away constness. In C++98, the intent was not entirely clear here,2466 // since all other paragraphs explicitly forbid casts to the same type.2467 // C++11 clarifies this case with p2.2468 //2469 // The only allowed types are: integral, enumeration, pointer, or2470 // pointer-to-member types. We also won't restrict Obj-C pointers either.2471 Kind = CK_NoOp;2472 TryCastResult Result = TC_NotApplicable;2473 if (SrcType->isIntegralOrEnumerationType() ||2474 SrcType->isAnyPointerType() ||2475 SrcType->isMemberPointerType() ||2476 SrcType->isBlockPointerType()) {2477 Result = TC_Success;2478 }2479 return Result;2480 }2481 2482 bool destIsPtr = DestType->isAnyPointerType() ||2483 DestType->isBlockPointerType();2484 bool srcIsPtr = SrcType->isAnyPointerType() ||2485 SrcType->isBlockPointerType();2486 if (!destIsPtr && !srcIsPtr) {2487 // Except for std::nullptr_t->integer and lvalue->reference, which are2488 // handled above, at least one of the two arguments must be a pointer.2489 return TC_NotApplicable;2490 }2491 2492 if (DestType->isIntegralType(Self.Context)) {2493 assert(srcIsPtr && "One type must be a pointer");2494 // C++ 5.2.10p4: A pointer can be explicitly converted to any integral2495 // type large enough to hold it; except in Microsoft mode, where the2496 // integral type size doesn't matter (except we don't allow bool).2497 if ((Self.Context.getTypeSize(SrcType) >2498 Self.Context.getTypeSize(DestType))) {2499 bool MicrosoftException =2500 Self.getLangOpts().MicrosoftExt && !DestType->isBooleanType();2501 if (MicrosoftException) {2502 unsigned Diag = SrcType->isVoidPointerType()2503 ? diag::warn_void_pointer_to_int_cast2504 : diag::warn_pointer_to_int_cast;2505 Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;2506 } else {2507 msg = diag::err_bad_reinterpret_cast_small_int;2508 return TC_Failed;2509 }2510 }2511 Kind = CK_PointerToIntegral;2512 return TC_Success;2513 }2514 2515 if (SrcType->isIntegralOrEnumerationType()) {2516 assert(destIsPtr && "One type must be a pointer");2517 checkIntToPointerCast(CStyle, OpRange, SrcExpr.get(), DestType, Self);2518 // C++ 5.2.10p5: A value of integral or enumeration type can be explicitly2519 // converted to a pointer.2520 // C++ 5.2.10p9: [Note: ...a null pointer constant of integral type is not2521 // necessarily converted to a null pointer value.]2522 Kind = CK_IntegralToPointer;2523 return TC_Success;2524 }2525 2526 if (!destIsPtr || !srcIsPtr) {2527 // With the valid non-pointer conversions out of the way, we can be even2528 // more stringent.2529 return TC_NotApplicable;2530 }2531 2532 // Cannot convert between block pointers and Objective-C object pointers.2533 if ((SrcType->isBlockPointerType() && DestType->isObjCObjectPointerType()) ||2534 (DestType->isBlockPointerType() && SrcType->isObjCObjectPointerType()))2535 return TC_NotApplicable;2536 2537 // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away constness.2538 // The C-style cast operator can.2539 TryCastResult SuccessResult = TC_Success;2540 if (auto CACK =2541 CastsAwayConstness(Self, SrcType, DestType, /*CheckCVR=*/!CStyle,2542 /*CheckObjCLifetime=*/CStyle))2543 SuccessResult = getCastAwayConstnessCastKind(CACK, msg);2544 2545 if (IsAddressSpaceConversion(SrcType, DestType)) {2546 Kind = CK_AddressSpaceConversion;2547 assert(SrcType->isPointerType() && DestType->isPointerType());2548 if (!CStyle &&2549 !DestType->getPointeeType().getQualifiers().isAddressSpaceSupersetOf(2550 SrcType->getPointeeType().getQualifiers(), Self.getASTContext())) {2551 SuccessResult = TC_Failed;2552 }2553 } else if (IsLValueCast) {2554 Kind = CK_LValueBitCast;2555 } else if (DestType->isObjCObjectPointerType()) {2556 Kind = Self.ObjC().PrepareCastToObjCObjectPointer(SrcExpr);2557 } else if (DestType->isBlockPointerType()) {2558 if (!SrcType->isBlockPointerType()) {2559 Kind = CK_AnyPointerToBlockPointerCast;2560 } else {2561 Kind = CK_BitCast;2562 }2563 } else {2564 Kind = CK_BitCast;2565 }2566 2567 // Any pointer can be cast to an Objective-C pointer type with a C-style2568 // cast.2569 if (CStyle && DestType->isObjCObjectPointerType()) {2570 return SuccessResult;2571 }2572 if (CStyle)2573 DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType);2574 2575 DiagnoseCallingConvCast(Self, SrcExpr, DestType, OpRange);2576 2577 // Not casting away constness, so the only remaining check is for compatible2578 // pointer categories.2579 2580 if (SrcType->isFunctionPointerType()) {2581 if (DestType->isFunctionPointerType()) {2582 // C++ 5.2.10p6: A pointer to a function can be explicitly converted to2583 // a pointer to a function of a different type.2584 return SuccessResult;2585 }2586 2587 // C++0x 5.2.10p8: Converting a pointer to a function into a pointer to2588 // an object type or vice versa is conditionally-supported.2589 // Compilers support it in C++03 too, though, because it's necessary for2590 // casting the return value of dlsym() and GetProcAddress().2591 // FIXME: Conditionally-supported behavior should be configurable in the2592 // TargetInfo or similar.2593 Self.Diag(OpRange.getBegin(),2594 Self.getLangOpts().CPlusPlus11 ?2595 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)2596 << OpRange;2597 return SuccessResult;2598 }2599 2600 if (DestType->isFunctionPointerType()) {2601 // See above.2602 Self.Diag(OpRange.getBegin(),2603 Self.getLangOpts().CPlusPlus11 ?2604 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)2605 << OpRange;2606 return SuccessResult;2607 }2608 2609 // Diagnose address space conversion in nested pointers.2610 QualType DestPtee = DestType->getPointeeType().isNull()2611 ? DestType->getPointeeType()2612 : DestType->getPointeeType()->getPointeeType();2613 QualType SrcPtee = SrcType->getPointeeType().isNull()2614 ? SrcType->getPointeeType()2615 : SrcType->getPointeeType()->getPointeeType();2616 while (!DestPtee.isNull() && !SrcPtee.isNull()) {2617 if (DestPtee.getAddressSpace() != SrcPtee.getAddressSpace()) {2618 Self.Diag(OpRange.getBegin(),2619 diag::warn_bad_cxx_cast_nested_pointer_addr_space)2620 << CStyle << SrcType << DestType << SrcExpr.get()->getSourceRange();2621 break;2622 }2623 DestPtee = DestPtee->getPointeeType();2624 SrcPtee = SrcPtee->getPointeeType();2625 }2626 2627 // C++ 5.2.10p7: A pointer to an object can be explicitly converted to2628 // a pointer to an object of different type.2629 // Void pointers are not specified, but supported by every compiler out there.2630 // So we finish by allowing everything that remains - it's got to be two2631 // object pointers.2632 return SuccessResult;2633}2634 2635static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr,2636 QualType DestType, bool CStyle,2637 unsigned &msg, CastKind &Kind) {2638 if (!Self.getLangOpts().OpenCL && !Self.getLangOpts().SYCLIsDevice)2639 // FIXME: As compiler doesn't have any information about overlapping addr2640 // spaces at the moment we have to be permissive here.2641 return TC_NotApplicable;2642 // Even though the logic below is general enough and can be applied to2643 // non-OpenCL mode too, we fast-path above because no other languages2644 // define overlapping address spaces currently.2645 auto SrcType = SrcExpr.get()->getType();2646 // FIXME: Should this be generalized to references? The reference parameter2647 // however becomes a reference pointee type here and therefore rejected.2648 // Perhaps this is the right behavior though according to C++.2649 auto SrcPtrType = SrcType->getAs<PointerType>();2650 if (!SrcPtrType)2651 return TC_NotApplicable;2652 auto DestPtrType = DestType->getAs<PointerType>();2653 if (!DestPtrType)2654 return TC_NotApplicable;2655 auto SrcPointeeType = SrcPtrType->getPointeeType();2656 auto DestPointeeType = DestPtrType->getPointeeType();2657 if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType,2658 Self.getASTContext())) {2659 msg = diag::err_bad_cxx_cast_addr_space_mismatch;2660 return TC_Failed;2661 }2662 auto SrcPointeeTypeWithoutAS =2663 Self.Context.removeAddrSpaceQualType(SrcPointeeType.getCanonicalType());2664 auto DestPointeeTypeWithoutAS =2665 Self.Context.removeAddrSpaceQualType(DestPointeeType.getCanonicalType());2666 if (Self.Context.hasSameType(SrcPointeeTypeWithoutAS,2667 DestPointeeTypeWithoutAS)) {2668 Kind = SrcPointeeType.getAddressSpace() == DestPointeeType.getAddressSpace()2669 ? CK_NoOp2670 : CK_AddressSpaceConversion;2671 return TC_Success;2672 } else {2673 return TC_NotApplicable;2674 }2675}2676 2677void CastOperation::checkAddressSpaceCast(QualType SrcType, QualType DestType) {2678 // In OpenCL only conversions between pointers to objects in overlapping2679 // addr spaces are allowed. v2.0 s6.5.5 - Generic addr space overlaps2680 // with any named one, except for constant.2681 2682 // Converting the top level pointee addrspace is permitted for compatible2683 // addrspaces (such as 'generic int *' to 'local int *' or vice versa), but2684 // if any of the nested pointee addrspaces differ, we emit a warning2685 // regardless of addrspace compatibility. This makes2686 // local int ** p;2687 // return (generic int **) p;2688 // warn even though local -> generic is permitted.2689 if (Self.getLangOpts().OpenCL) {2690 const Type *DestPtr, *SrcPtr;2691 bool Nested = false;2692 unsigned DiagID = diag::err_typecheck_incompatible_address_space;2693 DestPtr = Self.getASTContext().getCanonicalType(DestType.getTypePtr()),2694 SrcPtr = Self.getASTContext().getCanonicalType(SrcType.getTypePtr());2695 2696 while (isa<PointerType>(DestPtr) && isa<PointerType>(SrcPtr)) {2697 const PointerType *DestPPtr = cast<PointerType>(DestPtr);2698 const PointerType *SrcPPtr = cast<PointerType>(SrcPtr);2699 QualType DestPPointee = DestPPtr->getPointeeType();2700 QualType SrcPPointee = SrcPPtr->getPointeeType();2701 if (Nested2702 ? DestPPointee.getAddressSpace() != SrcPPointee.getAddressSpace()2703 : !DestPPointee.isAddressSpaceOverlapping(SrcPPointee,2704 Self.getASTContext())) {2705 Self.Diag(OpRange.getBegin(), DiagID)2706 << SrcType << DestType << AssignmentAction::Casting2707 << SrcExpr.get()->getSourceRange();2708 if (!Nested)2709 SrcExpr = ExprError();2710 return;2711 }2712 2713 DestPtr = DestPPtr->getPointeeType().getTypePtr();2714 SrcPtr = SrcPPtr->getPointeeType().getTypePtr();2715 Nested = true;2716 DiagID = diag::ext_nested_pointer_qualifier_mismatch;2717 }2718 }2719}2720 2721bool Sema::ShouldSplatAltivecScalarInCast(const VectorType *VecTy) {2722 bool SrcCompatXL = this->getLangOpts().getAltivecSrcCompat() ==2723 LangOptions::AltivecSrcCompatKind::XL;2724 VectorKind VKind = VecTy->getVectorKind();2725 2726 if ((VKind == VectorKind::AltiVecVector) ||2727 (SrcCompatXL && ((VKind == VectorKind::AltiVecBool) ||2728 (VKind == VectorKind::AltiVecPixel)))) {2729 return true;2730 }2731 return false;2732}2733 2734bool Sema::CheckAltivecInitFromScalar(SourceRange R, QualType VecTy,2735 QualType SrcTy) {2736 bool SrcCompatGCC = this->getLangOpts().getAltivecSrcCompat() ==2737 LangOptions::AltivecSrcCompatKind::GCC;2738 if (this->getLangOpts().AltiVec && SrcCompatGCC) {2739 this->Diag(R.getBegin(),2740 diag::err_invalid_conversion_between_vector_and_integer)2741 << VecTy << SrcTy << R;2742 return true;2743 }2744 return false;2745}2746 2747void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,2748 bool ListInitialization) {2749 assert(Self.getLangOpts().CPlusPlus);2750 2751 // Handle placeholders.2752 if (isPlaceholder()) {2753 // C-style casts can resolve __unknown_any types.2754 if (claimPlaceholder(BuiltinType::UnknownAny)) {2755 SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,2756 SrcExpr.get(), Kind,2757 ValueKind, BasePath);2758 return;2759 }2760 2761 checkNonOverloadPlaceholders();2762 if (SrcExpr.isInvalid())2763 return;2764 }2765 2766 // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".2767 // This test is outside everything else because it's the only case where2768 // a non-lvalue-reference target type does not lead to decay.2769 if (DestType->isVoidType()) {2770 Kind = CK_ToVoid;2771 2772 if (claimPlaceholder(BuiltinType::Overload)) {2773 Self.ResolveAndFixSingleFunctionTemplateSpecialization(2774 SrcExpr, /* Decay Function to ptr */ false,2775 /* Complain */ true, DestRange, DestType,2776 diag::err_bad_cstyle_cast_overload);2777 if (SrcExpr.isInvalid())2778 return;2779 }2780 2781 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());2782 return;2783 }2784 2785 // If the type is dependent, we won't do any other semantic analysis now.2786 if (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() ||2787 SrcExpr.get()->isValueDependent()) {2788 assert(Kind == CK_Dependent);2789 return;2790 }2791 2792 CheckedConversionKind CCK = FunctionalStyle2793 ? CheckedConversionKind::FunctionalCast2794 : CheckedConversionKind::CStyleCast;2795 if (Self.getLangOpts().HLSL) {2796 if (CheckHLSLCStyleCast(CCK))2797 return;2798 }2799 2800 if (ValueKind == VK_PRValue && !DestType->isRecordType() &&2801 !isPlaceholder(BuiltinType::Overload)) {2802 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());2803 if (SrcExpr.isInvalid())2804 return;2805 }2806 2807 // AltiVec vector initialization with a single literal.2808 if (const VectorType *vecTy = DestType->getAs<VectorType>()) {2809 if (Self.CheckAltivecInitFromScalar(OpRange, DestType,2810 SrcExpr.get()->getType())) {2811 SrcExpr = ExprError();2812 return;2813 }2814 if (Self.ShouldSplatAltivecScalarInCast(vecTy) &&2815 (SrcExpr.get()->getType()->isIntegerType() ||2816 SrcExpr.get()->getType()->isFloatingType())) {2817 Kind = CK_VectorSplat;2818 SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());2819 return;2820 }2821 }2822 2823 // WebAssembly tables cannot be cast.2824 QualType SrcType = SrcExpr.get()->getType();2825 if (SrcType->isWebAssemblyTableType()) {2826 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)2827 << 1 << SrcExpr.get()->getSourceRange();2828 SrcExpr = ExprError();2829 return;2830 }2831 2832 // C++ [expr.cast]p5: The conversions performed by2833 // - a const_cast,2834 // - a static_cast,2835 // - a static_cast followed by a const_cast,2836 // - a reinterpret_cast, or2837 // - a reinterpret_cast followed by a const_cast,2838 // can be performed using the cast notation of explicit type conversion.2839 // [...] If a conversion can be interpreted in more than one of the ways2840 // listed above, the interpretation that appears first in the list is used,2841 // even if a cast resulting from that interpretation is ill-formed.2842 // In plain language, this means trying a const_cast ...2843 // Note that for address space we check compatibility after const_cast.2844 unsigned msg = diag::err_bad_cxx_cast_generic;2845 TryCastResult tcr = TryConstCast(Self, SrcExpr, DestType,2846 /*CStyle*/ true, msg);2847 if (SrcExpr.isInvalid())2848 return;2849 if (isValidCast(tcr))2850 Kind = CK_NoOp;2851 2852 if (tcr == TC_NotApplicable) {2853 tcr = TryAddressSpaceCast(Self, SrcExpr, DestType, /*CStyle*/ true, msg,2854 Kind);2855 if (SrcExpr.isInvalid())2856 return;2857 2858 if (tcr == TC_NotApplicable) {2859 // ... or if that is not possible, a static_cast, ignoring const and2860 // addr space, ...2861 tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange, msg, Kind,2862 BasePath, ListInitialization);2863 if (SrcExpr.isInvalid())2864 return;2865 2866 if (tcr == TC_NotApplicable) {2867 // ... and finally a reinterpret_cast, ignoring const and addr space.2868 tcr = TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/ true,2869 OpRange, msg, Kind);2870 if (SrcExpr.isInvalid())2871 return;2872 }2873 }2874 }2875 2876 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&2877 isValidCast(tcr))2878 checkObjCConversion(CCK);2879 2880 if (tcr != TC_Success && msg != 0) {2881 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {2882 DeclAccessPair Found;2883 FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),2884 DestType,2885 /*Complain*/ true,2886 Found);2887 if (Fn) {2888 // If DestType is a function type (not to be confused with the function2889 // pointer type), it will be possible to resolve the function address,2890 // but the type cast should be considered as failure.2891 OverloadExpr *OE = OverloadExpr::find(SrcExpr.get()).Expression;2892 Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload)2893 << OE->getName() << DestType << OpRange2894 << OE->getQualifierLoc().getSourceRange();2895 Self.NoteAllOverloadCandidates(SrcExpr.get());2896 }2897 } else {2898 diagnoseBadCast(Self, msg, (FunctionalStyle ? CT_Functional : CT_CStyle),2899 OpRange, SrcExpr.get(), DestType, ListInitialization);2900 }2901 }2902 2903 if (isValidCast(tcr)) {2904 if (Kind == CK_BitCast)2905 checkCastAlign();2906 2907 if (unsigned DiagID = checkCastFunctionType(Self, SrcExpr, DestType))2908 Self.Diag(OpRange.getBegin(), DiagID)2909 << SrcExpr.get()->getType() << DestType << OpRange;2910 2911 } else {2912 SrcExpr = ExprError();2913 }2914}2915 2916// CheckHLSLCStyleCast - Returns `true` ihe cast is handled or errored as an2917// HLSL-specific cast. Returns false if the cast should be checked as a CXX2918// C-Style cast.2919bool CastOperation::CheckHLSLCStyleCast(CheckedConversionKind CCK) {2920 assert(Self.getLangOpts().HLSL && "Must be HLSL!");2921 QualType SrcTy = SrcExpr.get()->getType();2922 // HLSL has several unique forms of C-style casts which support aggregate to2923 // aggregate casting.2924 // This case should not trigger on regular vector cast, vector truncation2925 if (Self.HLSL().CanPerformElementwiseCast(SrcExpr.get(), DestType)) {2926 if (SrcTy->isConstantArrayType())2927 SrcExpr = Self.ImpCastExprToType(2928 SrcExpr.get(), Self.Context.getArrayParameterType(SrcTy),2929 CK_HLSLArrayRValue, VK_PRValue, nullptr, CCK);2930 else2931 SrcExpr = Self.DefaultLvalueConversion(SrcExpr.get());2932 Kind = CK_HLSLElementwiseCast;2933 return true;2934 }2935 2936 // This case should not trigger on regular vector splat2937 // If the relative order of this and the HLSLElementWise cast checks2938 // are changed, it might change which cast handles what in a few cases2939 if (Self.HLSL().CanPerformAggregateSplatCast(SrcExpr.get(), DestType)) {2940 SrcExpr = Self.DefaultLvalueConversion(SrcExpr.get());2941 const VectorType *VT = SrcTy->getAs<VectorType>();2942 // change splat from vec1 case to splat from scalar2943 if (VT && VT->getNumElements() == 1)2944 SrcExpr = Self.ImpCastExprToType(2945 SrcExpr.get(), VT->getElementType(), CK_HLSLVectorTruncation,2946 SrcExpr.get()->getValueKind(), nullptr, CCK);2947 // Inserting a scalar cast here allows for a simplified codegen in2948 // the case the destTy is a vector2949 if (const VectorType *DVT = DestType->getAs<VectorType>())2950 SrcExpr = Self.ImpCastExprToType(2951 SrcExpr.get(), DVT->getElementType(),2952 Self.PrepareScalarCast(SrcExpr, DVT->getElementType()),2953 SrcExpr.get()->getValueKind(), nullptr, CCK);2954 Kind = CK_HLSLAggregateSplatCast;2955 return true;2956 }2957 2958 // If the destination is an array, we've exhausted the valid HLSL casts, so we2959 // should emit a dignostic and stop processing.2960 if (DestType->isArrayType()) {2961 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic)2962 << 4 << SrcTy << DestType;2963 SrcExpr = ExprError();2964 return true;2965 }2966 return false;2967}2968 2969/// DiagnoseBadFunctionCast - Warn whenever a function call is cast to a2970/// non-matching type. Such as enum function call to int, int call to2971/// pointer; etc. Cast to 'void' is an exception.2972static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr,2973 QualType DestType) {2974 if (Self.Diags.isIgnored(diag::warn_bad_function_cast,2975 SrcExpr.get()->getExprLoc()))2976 return;2977 2978 if (!isa<CallExpr>(SrcExpr.get()))2979 return;2980 2981 QualType SrcType = SrcExpr.get()->getType();2982 if (DestType.getUnqualifiedType()->isVoidType())2983 return;2984 if ((SrcType->isAnyPointerType() || SrcType->isBlockPointerType())2985 && (DestType->isAnyPointerType() || DestType->isBlockPointerType()))2986 return;2987 if (SrcType->isIntegerType() && DestType->isIntegerType() &&2988 (SrcType->isBooleanType() == DestType->isBooleanType()) &&2989 (SrcType->isEnumeralType() == DestType->isEnumeralType()))2990 return;2991 if (SrcType->isRealFloatingType() && DestType->isRealFloatingType())2992 return;2993 if (SrcType->isEnumeralType() && DestType->isEnumeralType())2994 return;2995 if (SrcType->isComplexType() && DestType->isComplexType())2996 return;2997 if (SrcType->isComplexIntegerType() && DestType->isComplexIntegerType())2998 return;2999 if (SrcType->isFixedPointType() && DestType->isFixedPointType())3000 return;3001 3002 Self.Diag(SrcExpr.get()->getExprLoc(),3003 diag::warn_bad_function_cast)3004 << SrcType << DestType << SrcExpr.get()->getSourceRange();3005}3006 3007/// Check the semantics of a C-style cast operation, in C.3008void CastOperation::CheckCStyleCast() {3009 assert(!Self.getLangOpts().CPlusPlus);3010 3011 // C-style casts can resolve __unknown_any types.3012 if (claimPlaceholder(BuiltinType::UnknownAny)) {3013 SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,3014 SrcExpr.get(), Kind,3015 ValueKind, BasePath);3016 return;3017 }3018 3019 // C99 6.5.4p2: the cast type needs to be void or scalar and the expression3020 // type needs to be scalar.3021 if (DestType->isVoidType()) {3022 // We don't necessarily do lvalue-to-rvalue conversions on this.3023 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());3024 if (SrcExpr.isInvalid())3025 return;3026 3027 // Cast to void allows any expr type.3028 Kind = CK_ToVoid;3029 return;3030 }3031 3032 // If the type is dependent, we won't do any other semantic analysis now.3033 if (Self.getASTContext().isDependenceAllowed() &&3034 (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() ||3035 SrcExpr.get()->isValueDependent())) {3036 assert((DestType->containsErrors() || SrcExpr.get()->containsErrors() ||3037 SrcExpr.get()->containsErrors()) &&3038 "should only occur in error-recovery path.");3039 assert(Kind == CK_Dependent);3040 return;3041 }3042 3043 // Overloads are allowed with C extensions, so we need to support them.3044 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {3045 DeclAccessPair DAP;3046 if (FunctionDecl *FD = Self.ResolveAddressOfOverloadedFunction(3047 SrcExpr.get(), DestType, /*Complain=*/true, DAP))3048 SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr.get(), DAP, FD);3049 else3050 return;3051 assert(SrcExpr.isUsable());3052 }3053 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());3054 if (SrcExpr.isInvalid())3055 return;3056 QualType SrcType = SrcExpr.get()->getType();3057 3058 if (SrcType->isWebAssemblyTableType()) {3059 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)3060 << 1 << SrcExpr.get()->getSourceRange();3061 SrcExpr = ExprError();3062 return;3063 }3064 3065 assert(!SrcType->isPlaceholderType());3066 3067 checkAddressSpaceCast(SrcType, DestType);3068 if (SrcExpr.isInvalid())3069 return;3070 3071 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,3072 diag::err_typecheck_cast_to_incomplete)) {3073 SrcExpr = ExprError();3074 return;3075 }3076 3077 // Allow casting a sizeless built-in type to itself.3078 if (DestType->isSizelessBuiltinType() &&3079 Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {3080 Kind = CK_NoOp;3081 return;3082 }3083 3084 // Allow bitcasting between compatible SVE vector types.3085 if ((SrcType->isVectorType() || DestType->isVectorType()) &&3086 Self.isValidSveBitcast(SrcType, DestType)) {3087 Kind = CK_BitCast;3088 return;3089 }3090 3091 // Allow bitcasting between compatible RVV vector types.3092 if ((SrcType->isVectorType() || DestType->isVectorType()) &&3093 Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {3094 Kind = CK_BitCast;3095 return;3096 }3097 3098 if (!DestType->isScalarType() && !DestType->isVectorType() &&3099 !DestType->isMatrixType()) {3100 if (const RecordType *DestRecordTy =3101 DestType->getAsCanonical<RecordType>()) {3102 if (Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {3103 // GCC struct/union extension: allow cast to self.3104 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)3105 << DestType << SrcExpr.get()->getSourceRange();3106 Kind = CK_NoOp;3107 return;3108 }3109 3110 // GCC's cast to union extension.3111 if (RecordDecl *RD = DestRecordTy->getDecl(); RD->isUnion()) {3112 if (CastExpr::getTargetFieldForToUnionCast(RD->getDefinitionOrSelf(),3113 SrcType)) {3114 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)3115 << SrcExpr.get()->getSourceRange();3116 Kind = CK_ToUnion;3117 return;3118 }3119 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)3120 << SrcType << SrcExpr.get()->getSourceRange();3121 SrcExpr = ExprError();3122 return;3123 }3124 }3125 3126 // OpenCL v2.0 s6.13.10 - Allow casts from '0' to event_t type.3127 if (Self.getLangOpts().OpenCL && DestType->isEventT()) {3128 Expr::EvalResult Result;3129 if (SrcExpr.get()->EvaluateAsInt(Result, Self.Context)) {3130 llvm::APSInt CastInt = Result.Val.getInt();3131 if (0 == CastInt) {3132 Kind = CK_ZeroToOCLOpaqueType;3133 return;3134 }3135 Self.Diag(OpRange.getBegin(),3136 diag::err_opencl_cast_non_zero_to_event_t)3137 << toString(CastInt, 10) << SrcExpr.get()->getSourceRange();3138 SrcExpr = ExprError();3139 return;3140 }3141 }3142 3143 // Reject any other conversions to non-scalar types.3144 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar)3145 << DestType << SrcExpr.get()->getSourceRange();3146 SrcExpr = ExprError();3147 return;3148 }3149 3150 // The type we're casting to is known to be a scalar, a vector, or a matrix.3151 3152 // Require the operand to be a scalar, a vector, or a matrix.3153 if (!SrcType->isScalarType() && !SrcType->isVectorType() &&3154 !SrcType->isMatrixType()) {3155 Self.Diag(SrcExpr.get()->getExprLoc(),3156 diag::err_typecheck_expect_scalar_operand)3157 << SrcType << SrcExpr.get()->getSourceRange();3158 SrcExpr = ExprError();3159 return;3160 }3161 3162 // C23 6.5.5p4:3163 // ... The type nullptr_t shall not be converted to any type other than3164 // void, bool or a pointer type.If the target type is nullptr_t, the cast3165 // expression shall be a null pointer constant or have type nullptr_t.3166 if (SrcType->isNullPtrType()) {3167 // FIXME: 6.3.2.4p2 says that nullptr_t can be converted to itself, but3168 // 6.5.4p4 is a constraint check and nullptr_t is not void, bool, or a3169 // pointer type. We're not going to diagnose that as a constraint violation.3170 if (!DestType->isVoidType() && !DestType->isBooleanType() &&3171 !DestType->isPointerType() && !DestType->isNullPtrType()) {3172 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)3173 << /*nullptr to type*/ 0 << DestType;3174 SrcExpr = ExprError();3175 return;3176 }3177 if (DestType->isBooleanType()) {3178 SrcExpr = ImplicitCastExpr::Create(3179 Self.Context, DestType, CK_PointerToBoolean, SrcExpr.get(), nullptr,3180 VK_PRValue, Self.CurFPFeatureOverrides());3181 3182 } else if (!DestType->isNullPtrType()) {3183 // Implicitly cast from the null pointer type to the type of the3184 // destination.3185 CastKind CK = DestType->isPointerType() ? CK_NullToPointer : CK_BitCast;3186 SrcExpr = ImplicitCastExpr::Create(Self.Context, DestType, CK,3187 SrcExpr.get(), nullptr, VK_PRValue,3188 Self.CurFPFeatureOverrides());3189 }3190 }3191 3192 if (DestType->isNullPtrType() && !SrcType->isNullPtrType()) {3193 if (!SrcExpr.get()->isNullPointerConstant(Self.Context,3194 Expr::NPC_NeverValueDependent)) {3195 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)3196 << /*type to nullptr*/ 1 << SrcType;3197 SrcExpr = ExprError();3198 return;3199 }3200 // Need to convert the source from whatever its type is to a null pointer3201 // type first.3202 SrcExpr = ImplicitCastExpr::Create(Self.Context, DestType, CK_NullToPointer,3203 SrcExpr.get(), nullptr, VK_PRValue,3204 Self.CurFPFeatureOverrides());3205 }3206 3207 if (DestType->isExtVectorType()) {3208 SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind);3209 return;3210 }3211 3212 if (DestType->getAs<MatrixType>() || SrcType->getAs<MatrixType>()) {3213 if (Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind))3214 SrcExpr = ExprError();3215 return;3216 }3217 3218 if (const VectorType *DestVecTy = DestType->getAs<VectorType>()) {3219 if (Self.CheckAltivecInitFromScalar(OpRange, DestType, SrcType)) {3220 SrcExpr = ExprError();3221 return;3222 }3223 if (Self.ShouldSplatAltivecScalarInCast(DestVecTy) &&3224 (SrcType->isIntegerType() || SrcType->isFloatingType())) {3225 Kind = CK_VectorSplat;3226 SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());3227 } else if (Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {3228 SrcExpr = ExprError();3229 }3230 return;3231 }3232 3233 if (SrcType->isVectorType()) {3234 if (Self.CheckVectorCast(OpRange, SrcType, DestType, Kind))3235 SrcExpr = ExprError();3236 return;3237 }3238 3239 // The source and target types are both scalars, i.e.3240 // - arithmetic types (fundamental, enum, and complex)3241 // - all kinds of pointers3242 // Note that member pointers were filtered out with C++, above.3243 3244 if (isa<ObjCSelectorExpr>(SrcExpr.get())) {3245 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr);3246 SrcExpr = ExprError();3247 return;3248 }3249 3250 // If either type is a pointer, the other type has to be either an3251 // integer or a pointer.3252 if (!DestType->isArithmeticType()) {3253 if (!SrcType->isIntegralType(Self.Context) && SrcType->isArithmeticType()) {3254 Self.Diag(SrcExpr.get()->getExprLoc(),3255 diag::err_cast_pointer_from_non_pointer_int)3256 << SrcType << SrcExpr.get()->getSourceRange();3257 SrcExpr = ExprError();3258 return;3259 }3260 checkIntToPointerCast(/* CStyle */ true, OpRange, SrcExpr.get(), DestType,3261 Self);3262 } else if (!SrcType->isArithmeticType()) {3263 if (!DestType->isIntegralType(Self.Context) &&3264 DestType->isArithmeticType()) {3265 Self.Diag(SrcExpr.get()->getBeginLoc(),3266 diag::err_cast_pointer_to_non_pointer_int)3267 << DestType << SrcExpr.get()->getSourceRange();3268 SrcExpr = ExprError();3269 return;3270 }3271 3272 if ((Self.Context.getTypeSize(SrcType) >3273 Self.Context.getTypeSize(DestType)) &&3274 !DestType->isBooleanType()) {3275 // C 6.3.2.3p6: Any pointer type may be converted to an integer type.3276 // Except as previously specified, the result is implementation-defined.3277 // If the result cannot be represented in the integer type, the behavior3278 // is undefined. The result need not be in the range of values of any3279 // integer type.3280 unsigned Diag;3281 if (SrcType->isVoidPointerType())3282 Diag = DestType->isEnumeralType() ? diag::warn_void_pointer_to_enum_cast3283 : diag::warn_void_pointer_to_int_cast;3284 else if (DestType->isEnumeralType())3285 Diag = diag::warn_pointer_to_enum_cast;3286 else3287 Diag = diag::warn_pointer_to_int_cast;3288 Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;3289 }3290 }3291 3292 if (Self.getLangOpts().OpenCL && !Self.getOpenCLOptions().isAvailableOption(3293 "cl_khr_fp16", Self.getLangOpts())) {3294 if (DestType->isHalfType()) {3295 Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half)3296 << DestType << SrcExpr.get()->getSourceRange();3297 SrcExpr = ExprError();3298 return;3299 }3300 }3301 3302 // ARC imposes extra restrictions on casts.3303 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) {3304 checkObjCConversion(CheckedConversionKind::CStyleCast);3305 if (SrcExpr.isInvalid())3306 return;3307 3308 const PointerType *CastPtr = DestType->getAs<PointerType>();3309 if (Self.getLangOpts().ObjCAutoRefCount && CastPtr) {3310 if (const PointerType *ExprPtr = SrcType->getAs<PointerType>()) {3311 Qualifiers CastQuals = CastPtr->getPointeeType().getQualifiers();3312 Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();3313 if (CastPtr->getPointeeType()->isObjCLifetimeType() &&3314 ExprPtr->getPointeeType()->isObjCLifetimeType() &&3315 !CastQuals.compatiblyIncludesObjCLifetime(ExprQuals)) {3316 Self.Diag(SrcExpr.get()->getBeginLoc(),3317 diag::err_typecheck_incompatible_ownership)3318 << SrcType << DestType << AssignmentAction::Casting3319 << SrcExpr.get()->getSourceRange();3320 return;3321 }3322 }3323 } else if (!Self.ObjC().CheckObjCARCUnavailableWeakConversion(DestType,3324 SrcType)) {3325 Self.Diag(SrcExpr.get()->getBeginLoc(),3326 diag::err_arc_convesion_of_weak_unavailable)3327 << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange();3328 SrcExpr = ExprError();3329 return;3330 }3331 }3332 3333 if (unsigned DiagID = checkCastFunctionType(Self, SrcExpr, DestType))3334 Self.Diag(OpRange.getBegin(), DiagID) << SrcType << DestType << OpRange;3335 3336 if (isa<PointerType>(SrcType) && isa<PointerType>(DestType)) {3337 QualType SrcTy = cast<PointerType>(SrcType)->getPointeeType();3338 QualType DestTy = cast<PointerType>(DestType)->getPointeeType();3339 3340 const RecordDecl *SrcRD = SrcTy->getAsRecordDecl();3341 const RecordDecl *DestRD = DestTy->getAsRecordDecl();3342 3343 if (SrcRD && DestRD && SrcRD->hasAttr<RandomizeLayoutAttr>() &&3344 SrcRD != DestRD) {3345 // The struct we are casting the pointer from was randomized.3346 Self.Diag(OpRange.getBegin(), diag::err_cast_from_randomized_struct)3347 << SrcType << DestType;3348 SrcExpr = ExprError();3349 return;3350 }3351 }3352 3353 DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType);3354 DiagnoseCallingConvCast(Self, SrcExpr, DestType, OpRange);3355 DiagnoseBadFunctionCast(Self, SrcExpr, DestType);3356 Kind = Self.PrepareScalarCast(SrcExpr, DestType);3357 if (SrcExpr.isInvalid())3358 return;3359 3360 if (Kind == CK_BitCast)3361 checkCastAlign();3362}3363 3364void CastOperation::CheckBuiltinBitCast() {3365 QualType SrcType = SrcExpr.get()->getType();3366 3367 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,3368 diag::err_typecheck_cast_to_incomplete) ||3369 Self.RequireCompleteType(OpRange.getBegin(), SrcType,3370 diag::err_incomplete_type)) {3371 SrcExpr = ExprError();3372 return;3373 }3374 3375 if (SrcExpr.get()->isPRValue())3376 SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),3377 /*IsLValueReference=*/false);3378 3379 CharUnits DestSize = Self.Context.getTypeSizeInChars(DestType);3380 CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType);3381 if (DestSize != SourceSize) {3382 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch)3383 << SrcType << DestType << (int)SourceSize.getQuantity()3384 << (int)DestSize.getQuantity();3385 SrcExpr = ExprError();3386 return;3387 }3388 3389 if (!DestType.isTriviallyCopyableType(Self.Context)) {3390 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)3391 << 1;3392 SrcExpr = ExprError();3393 return;3394 }3395 3396 if (!SrcType.isTriviallyCopyableType(Self.Context)) {3397 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)3398 << 0;3399 SrcExpr = ExprError();3400 return;3401 }3402 3403 Kind = CK_LValueToRValueBitCast;3404}3405 3406/// DiagnoseCastQual - Warn whenever casts discards a qualifiers, be it either3407/// const, volatile or both.3408static void DiagnoseCastQual(Sema &Self, const ExprResult &SrcExpr,3409 QualType DestType) {3410 if (SrcExpr.isInvalid())3411 return;3412 3413 QualType SrcType = SrcExpr.get()->getType();3414 if (!((SrcType->isAnyPointerType() && DestType->isAnyPointerType()) ||3415 DestType->isLValueReferenceType()))3416 return;3417 3418 QualType TheOffendingSrcType, TheOffendingDestType;3419 Qualifiers CastAwayQualifiers;3420 if (CastsAwayConstness(Self, SrcType, DestType, true, false,3421 &TheOffendingSrcType, &TheOffendingDestType,3422 &CastAwayQualifiers) !=3423 CastAwayConstnessKind::CACK_Similar)3424 return;3425 3426 // FIXME: 'restrict' is not properly handled here.3427 int qualifiers = -1;3428 if (CastAwayQualifiers.hasConst() && CastAwayQualifiers.hasVolatile()) {3429 qualifiers = 0;3430 } else if (CastAwayQualifiers.hasConst()) {3431 qualifiers = 1;3432 } else if (CastAwayQualifiers.hasVolatile()) {3433 qualifiers = 2;3434 }3435 // This is a variant of int **x; const int **y = (const int **)x;3436 if (qualifiers == -1)3437 Self.Diag(SrcExpr.get()->getBeginLoc(), diag::warn_cast_qual2)3438 << SrcType << DestType;3439 else3440 Self.Diag(SrcExpr.get()->getBeginLoc(), diag::warn_cast_qual)3441 << TheOffendingSrcType << TheOffendingDestType << qualifiers;3442}3443 3444ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc,3445 TypeSourceInfo *CastTypeInfo,3446 SourceLocation RPLoc,3447 Expr *CastExpr) {3448 CastOperation Op(*this, CastTypeInfo->getType(), CastExpr);3449 Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();3450 Op.OpRange = CastOperation::OpRangeType(LPLoc, LPLoc, CastExpr->getEndLoc());3451 3452 if (getLangOpts().CPlusPlus) {3453 Op.CheckCXXCStyleCast(/*FunctionalCast=*/ false,3454 isa<InitListExpr>(CastExpr));3455 } else {3456 Op.CheckCStyleCast();3457 }3458 3459 if (Op.SrcExpr.isInvalid())3460 return ExprError();3461 3462 // -Wcast-qual3463 DiagnoseCastQual(Op.Self, Op.SrcExpr, Op.DestType);3464 3465 Op.checkQualifiedDestType();3466 3467 return Op.complete(CStyleCastExpr::Create(3468 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),3469 &Op.BasePath, CurFPFeatureOverrides(), CastTypeInfo, LPLoc, RPLoc));3470}3471 3472ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,3473 QualType Type,3474 SourceLocation LPLoc,3475 Expr *CastExpr,3476 SourceLocation RPLoc) {3477 assert(LPLoc.isValid() && "List-initialization shouldn't get here.");3478 CastOperation Op(*this, Type, CastExpr);3479 Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();3480 Op.OpRange =3481 CastOperation::OpRangeType(Op.DestRange.getBegin(), LPLoc, RPLoc);3482 3483 Op.CheckCXXCStyleCast(/*FunctionalCast=*/true, /*ListInit=*/false);3484 if (Op.SrcExpr.isInvalid())3485 return ExprError();3486 3487 Op.checkQualifiedDestType();3488 3489 // -Wcast-qual3490 DiagnoseCastQual(Op.Self, Op.SrcExpr, Op.DestType);3491 3492 return Op.complete(CXXFunctionalCastExpr::Create(3493 Context, Op.ResultType, Op.ValueKind, CastTypeInfo, Op.Kind,3494 Op.SrcExpr.get(), &Op.BasePath, CurFPFeatureOverrides(), LPLoc, RPLoc));3495}3496