xref: /freebsd-src/contrib/llvm-project/clang/lib/Sema/SemaCast.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- SemaCast.cpp - Semantic Analysis for Casts -----------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file implements semantic analysis for cast expressions, including
100b57cec5SDimitry Andric //  1) C-style casts like '(int) x'
110b57cec5SDimitry Andric //  2) C++ functional casts like 'int(x)'
120b57cec5SDimitry Andric //  3) C++ named casts like 'static_cast<int>(x)'
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
17fe6060f1SDimitry Andric #include "clang/AST/ASTStructuralEquivalence.h"
180b57cec5SDimitry Andric #include "clang/AST/CXXInheritance.h"
190b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
200b57cec5SDimitry Andric #include "clang/AST/ExprObjC.h"
210b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h"
220b57cec5SDimitry Andric #include "clang/Basic/PartialDiagnostic.h"
230b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
240b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h"
250b57cec5SDimitry Andric #include "clang/Sema/Initialization.h"
26fe6060f1SDimitry Andric #include "clang/Sema/SemaInternal.h"
27*0fca6ea1SDimitry Andric #include "clang/Sema/SemaObjC.h"
28*0fca6ea1SDimitry Andric #include "clang/Sema/SemaRISCV.h"
290b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
3006c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h"
310b57cec5SDimitry Andric #include <set>
320b57cec5SDimitry Andric using namespace clang;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric enum TryCastResult {
370b57cec5SDimitry Andric   TC_NotApplicable, ///< The cast method is not applicable.
380b57cec5SDimitry Andric   TC_Success,       ///< The cast method is appropriate and successful.
390b57cec5SDimitry Andric   TC_Extension,     ///< The cast method is appropriate and accepted as a
400b57cec5SDimitry Andric                     ///< language extension.
410b57cec5SDimitry Andric   TC_Failed         ///< The cast method is appropriate, but failed. A
420b57cec5SDimitry Andric                     ///< diagnostic has been emitted.
430b57cec5SDimitry Andric };
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric static bool isValidCast(TryCastResult TCR) {
460b57cec5SDimitry Andric   return TCR == TC_Success || TCR == TC_Extension;
470b57cec5SDimitry Andric }
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric enum CastType {
500b57cec5SDimitry Andric   CT_Const,       ///< const_cast
510b57cec5SDimitry Andric   CT_Static,      ///< static_cast
520b57cec5SDimitry Andric   CT_Reinterpret, ///< reinterpret_cast
530b57cec5SDimitry Andric   CT_Dynamic,     ///< dynamic_cast
540b57cec5SDimitry Andric   CT_CStyle,      ///< (Type)expr
555ffd83dbSDimitry Andric   CT_Functional,  ///< Type(expr)
565ffd83dbSDimitry Andric   CT_Addrspace    ///< addrspace_cast
570b57cec5SDimitry Andric };
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric namespace {
600b57cec5SDimitry Andric   struct CastOperation {
610b57cec5SDimitry Andric     CastOperation(Sema &S, QualType destType, ExprResult src)
620b57cec5SDimitry Andric       : Self(S), SrcExpr(src), DestType(destType),
630b57cec5SDimitry Andric         ResultType(destType.getNonLValueExprType(S.Context)),
640b57cec5SDimitry Andric         ValueKind(Expr::getValueKindForType(destType)),
650b57cec5SDimitry Andric         Kind(CK_Dependent), IsARCUnbridgedCast(false) {
660b57cec5SDimitry Andric 
67fe6060f1SDimitry Andric       // C++ [expr.type]/8.2.2:
68fe6060f1SDimitry Andric       //   If a pr-value initially has the type cv-T, where T is a
69fe6060f1SDimitry Andric       //   cv-unqualified non-class, non-array type, the type of the
70fe6060f1SDimitry Andric       //   expression is adjusted to T prior to any further analysis.
715f757f3fSDimitry Andric       // C23 6.5.4p6:
7206c3fb27SDimitry Andric       //   Preceding an expression by a parenthesized type name converts the
7306c3fb27SDimitry Andric       //   value of the expression to the unqualified, non-atomic version of
7406c3fb27SDimitry Andric       //   the named type.
75fe6060f1SDimitry Andric       if (!S.Context.getLangOpts().ObjC && !DestType->isRecordType() &&
76fe6060f1SDimitry Andric           !DestType->isArrayType()) {
7706c3fb27SDimitry Andric         DestType = DestType.getAtomicUnqualifiedType();
78fe6060f1SDimitry Andric       }
79fe6060f1SDimitry Andric 
800b57cec5SDimitry Andric       if (const BuiltinType *placeholder =
810b57cec5SDimitry Andric             src.get()->getType()->getAsPlaceholderType()) {
820b57cec5SDimitry Andric         PlaceholderKind = placeholder->getKind();
830b57cec5SDimitry Andric       } else {
840b57cec5SDimitry Andric         PlaceholderKind = (BuiltinType::Kind) 0;
850b57cec5SDimitry Andric       }
860b57cec5SDimitry Andric     }
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric     Sema &Self;
890b57cec5SDimitry Andric     ExprResult SrcExpr;
900b57cec5SDimitry Andric     QualType DestType;
910b57cec5SDimitry Andric     QualType ResultType;
920b57cec5SDimitry Andric     ExprValueKind ValueKind;
930b57cec5SDimitry Andric     CastKind Kind;
940b57cec5SDimitry Andric     BuiltinType::Kind PlaceholderKind;
950b57cec5SDimitry Andric     CXXCastPath BasePath;
960b57cec5SDimitry Andric     bool IsARCUnbridgedCast;
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric     SourceRange OpRange;
990b57cec5SDimitry Andric     SourceRange DestRange;
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric     // Top-level semantics-checking routines.
1020b57cec5SDimitry Andric     void CheckConstCast();
1030b57cec5SDimitry Andric     void CheckReinterpretCast();
1040b57cec5SDimitry Andric     void CheckStaticCast();
1050b57cec5SDimitry Andric     void CheckDynamicCast();
1060b57cec5SDimitry Andric     void CheckCXXCStyleCast(bool FunctionalCast, bool ListInitialization);
1070b57cec5SDimitry Andric     void CheckCStyleCast();
1080b57cec5SDimitry Andric     void CheckBuiltinBitCast();
1095ffd83dbSDimitry Andric     void CheckAddrspaceCast();
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric     void updatePartOfExplicitCastFlags(CastExpr *CE) {
1120b57cec5SDimitry Andric       // Walk down from the CE to the OrigSrcExpr, and mark all immediate
1130b57cec5SDimitry Andric       // ImplicitCastExpr's as being part of ExplicitCastExpr. The original CE
1140b57cec5SDimitry Andric       // (which is a ExplicitCastExpr), and the OrigSrcExpr are not touched.
1150b57cec5SDimitry Andric       for (; auto *ICE = dyn_cast<ImplicitCastExpr>(CE->getSubExpr()); CE = ICE)
1160b57cec5SDimitry Andric         ICE->setIsPartOfExplicitCast(true);
1170b57cec5SDimitry Andric     }
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric     /// Complete an apparently-successful cast operation that yields
1200b57cec5SDimitry Andric     /// the given expression.
1210b57cec5SDimitry Andric     ExprResult complete(CastExpr *castExpr) {
1220b57cec5SDimitry Andric       // If this is an unbridged cast, wrap the result in an implicit
1230b57cec5SDimitry Andric       // cast that yields the unbridged-cast placeholder type.
1240b57cec5SDimitry Andric       if (IsARCUnbridgedCast) {
125e8d8bef9SDimitry Andric         castExpr = ImplicitCastExpr::Create(
126e8d8bef9SDimitry Andric             Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent,
127e8d8bef9SDimitry Andric             castExpr, nullptr, castExpr->getValueKind(),
128e8d8bef9SDimitry Andric             Self.CurFPFeatureOverrides());
1290b57cec5SDimitry Andric       }
1300b57cec5SDimitry Andric       updatePartOfExplicitCastFlags(castExpr);
1310b57cec5SDimitry Andric       return castExpr;
1320b57cec5SDimitry Andric     }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric     // Internal convenience methods.
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric     /// Try to handle the given placeholder expression kind.  Return
1370b57cec5SDimitry Andric     /// true if the source expression has the appropriate placeholder
1380b57cec5SDimitry Andric     /// kind.  A placeholder can only be claimed once.
1390b57cec5SDimitry Andric     bool claimPlaceholder(BuiltinType::Kind K) {
1400b57cec5SDimitry Andric       if (PlaceholderKind != K) return false;
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric       PlaceholderKind = (BuiltinType::Kind) 0;
1430b57cec5SDimitry Andric       return true;
1440b57cec5SDimitry Andric     }
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric     bool isPlaceholder() const {
1470b57cec5SDimitry Andric       return PlaceholderKind != 0;
1480b57cec5SDimitry Andric     }
1490b57cec5SDimitry Andric     bool isPlaceholder(BuiltinType::Kind K) const {
1500b57cec5SDimitry Andric       return PlaceholderKind == K;
1510b57cec5SDimitry Andric     }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric     // Language specific cast restrictions for address spaces.
1540b57cec5SDimitry Andric     void checkAddressSpaceCast(QualType SrcType, QualType DestType);
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric     void checkCastAlign() {
1570b57cec5SDimitry Andric       Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
1580b57cec5SDimitry Andric     }
1590b57cec5SDimitry Andric 
160*0fca6ea1SDimitry Andric     void checkObjCConversion(CheckedConversionKind CCK) {
1610b57cec5SDimitry Andric       assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers());
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric       Expr *src = SrcExpr.get();
164*0fca6ea1SDimitry Andric       if (Self.ObjC().CheckObjCConversion(OpRange, DestType, src, CCK) ==
165*0fca6ea1SDimitry Andric           SemaObjC::ACR_unbridged)
1660b57cec5SDimitry Andric         IsARCUnbridgedCast = true;
1670b57cec5SDimitry Andric       SrcExpr = src;
1680b57cec5SDimitry Andric     }
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric     /// Check for and handle non-overload placeholder expressions.
1710b57cec5SDimitry Andric     void checkNonOverloadPlaceholders() {
1720b57cec5SDimitry Andric       if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
1730b57cec5SDimitry Andric         return;
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric       SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
1760b57cec5SDimitry Andric       if (SrcExpr.isInvalid())
1770b57cec5SDimitry Andric         return;
1780b57cec5SDimitry Andric       PlaceholderKind = (BuiltinType::Kind) 0;
1790b57cec5SDimitry Andric     }
1800b57cec5SDimitry Andric   };
1815ffd83dbSDimitry Andric 
1825ffd83dbSDimitry Andric   void CheckNoDeref(Sema &S, const QualType FromType, const QualType ToType,
1835ffd83dbSDimitry Andric                     SourceLocation OpLoc) {
1845ffd83dbSDimitry Andric     if (const auto *PtrType = dyn_cast<PointerType>(FromType)) {
1855ffd83dbSDimitry Andric       if (PtrType->getPointeeType()->hasAttr(attr::NoDeref)) {
1865ffd83dbSDimitry Andric         if (const auto *DestType = dyn_cast<PointerType>(ToType)) {
1875ffd83dbSDimitry Andric           if (!DestType->getPointeeType()->hasAttr(attr::NoDeref)) {
1885ffd83dbSDimitry Andric             S.Diag(OpLoc, diag::warn_noderef_to_dereferenceable_pointer);
1895ffd83dbSDimitry Andric           }
1905ffd83dbSDimitry Andric         }
1915ffd83dbSDimitry Andric       }
1925ffd83dbSDimitry Andric     }
1935ffd83dbSDimitry Andric   }
1945ffd83dbSDimitry Andric 
1955ffd83dbSDimitry Andric   struct CheckNoDerefRAII {
1965ffd83dbSDimitry Andric     CheckNoDerefRAII(CastOperation &Op) : Op(Op) {}
1975ffd83dbSDimitry Andric     ~CheckNoDerefRAII() {
1985ffd83dbSDimitry Andric       if (!Op.SrcExpr.isInvalid())
1995ffd83dbSDimitry Andric         CheckNoDeref(Op.Self, Op.SrcExpr.get()->getType(), Op.ResultType,
2005ffd83dbSDimitry Andric                      Op.OpRange.getBegin());
2015ffd83dbSDimitry Andric     }
2025ffd83dbSDimitry Andric 
2035ffd83dbSDimitry Andric     CastOperation &Op;
2045ffd83dbSDimitry Andric   };
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric static void DiagnoseCastQual(Sema &Self, const ExprResult &SrcExpr,
2080b57cec5SDimitry Andric                              QualType DestType);
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric // The Try functions attempt a specific way of casting. If they succeed, they
2110b57cec5SDimitry Andric // return TC_Success. If their way of casting is not appropriate for the given
2120b57cec5SDimitry Andric // arguments, they return TC_NotApplicable and *may* set diag to a diagnostic
2130b57cec5SDimitry Andric // to emit if no other way succeeds. If their way of casting is appropriate but
2140b57cec5SDimitry Andric // fails, they return TC_Failed and *must* set diag; they can set it to 0 if
2150b57cec5SDimitry Andric // they emit a specialized diagnostic.
2160b57cec5SDimitry Andric // All diagnostics returned by these functions must expect the same three
2170b57cec5SDimitry Andric // arguments:
2180b57cec5SDimitry Andric // %0: Cast Type (a value from the CastType enumeration)
2190b57cec5SDimitry Andric // %1: Source Type
2200b57cec5SDimitry Andric // %2: Destination Type
2210b57cec5SDimitry Andric static TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr,
2220b57cec5SDimitry Andric                                            QualType DestType, bool CStyle,
2230b57cec5SDimitry Andric                                            CastKind &Kind,
2240b57cec5SDimitry Andric                                            CXXCastPath &BasePath,
2250b57cec5SDimitry Andric                                            unsigned &msg);
2260b57cec5SDimitry Andric static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr,
2270b57cec5SDimitry Andric                                                QualType DestType, bool CStyle,
2280b57cec5SDimitry Andric                                                SourceRange OpRange,
2290b57cec5SDimitry Andric                                                unsigned &msg,
2300b57cec5SDimitry Andric                                                CastKind &Kind,
2310b57cec5SDimitry Andric                                                CXXCastPath &BasePath);
2320b57cec5SDimitry Andric static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType,
2330b57cec5SDimitry Andric                                               QualType DestType, bool CStyle,
2340b57cec5SDimitry Andric                                               SourceRange OpRange,
2350b57cec5SDimitry Andric                                               unsigned &msg,
2360b57cec5SDimitry Andric                                               CastKind &Kind,
2370b57cec5SDimitry Andric                                               CXXCastPath &BasePath);
2380b57cec5SDimitry Andric static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,
2390b57cec5SDimitry Andric                                        CanQualType DestType, bool CStyle,
2400b57cec5SDimitry Andric                                        SourceRange OpRange,
2410b57cec5SDimitry Andric                                        QualType OrigSrcType,
2420b57cec5SDimitry Andric                                        QualType OrigDestType, unsigned &msg,
2430b57cec5SDimitry Andric                                        CastKind &Kind,
2440b57cec5SDimitry Andric                                        CXXCastPath &BasePath);
2450b57cec5SDimitry Andric static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr,
2460b57cec5SDimitry Andric                                                QualType SrcType,
2470b57cec5SDimitry Andric                                                QualType DestType,bool CStyle,
2480b57cec5SDimitry Andric                                                SourceRange OpRange,
2490b57cec5SDimitry Andric                                                unsigned &msg,
2500b57cec5SDimitry Andric                                                CastKind &Kind,
2510b57cec5SDimitry Andric                                                CXXCastPath &BasePath);
2520b57cec5SDimitry Andric 
253*0fca6ea1SDimitry Andric static TryCastResult
254*0fca6ea1SDimitry Andric TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
255*0fca6ea1SDimitry Andric                       CheckedConversionKind CCK, SourceRange OpRange,
256*0fca6ea1SDimitry Andric                       unsigned &msg, CastKind &Kind, bool ListInitialization);
2570b57cec5SDimitry Andric static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
258*0fca6ea1SDimitry Andric                                    QualType DestType, CheckedConversionKind CCK,
259*0fca6ea1SDimitry Andric                                    SourceRange OpRange, unsigned &msg,
260*0fca6ea1SDimitry Andric                                    CastKind &Kind, CXXCastPath &BasePath,
2610b57cec5SDimitry Andric                                    bool ListInitialization);
2620b57cec5SDimitry Andric static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr,
2630b57cec5SDimitry Andric                                   QualType DestType, bool CStyle,
2640b57cec5SDimitry Andric                                   unsigned &msg);
2650b57cec5SDimitry Andric static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
2660b57cec5SDimitry Andric                                         QualType DestType, bool CStyle,
2675ffd83dbSDimitry Andric                                         SourceRange OpRange, unsigned &msg,
2680b57cec5SDimitry Andric                                         CastKind &Kind);
2695ffd83dbSDimitry Andric static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr,
2705ffd83dbSDimitry Andric                                          QualType DestType, bool CStyle,
2715ffd83dbSDimitry Andric                                          unsigned &msg, CastKind &Kind);
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric ExprResult
2740b57cec5SDimitry Andric Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
2750b57cec5SDimitry Andric                         SourceLocation LAngleBracketLoc, Declarator &D,
2760b57cec5SDimitry Andric                         SourceLocation RAngleBracketLoc,
2770b57cec5SDimitry Andric                         SourceLocation LParenLoc, Expr *E,
2780b57cec5SDimitry Andric                         SourceLocation RParenLoc) {
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   assert(!D.isInvalidType());
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   TypeSourceInfo *TInfo = GetTypeForDeclaratorCast(D, E->getType());
2830b57cec5SDimitry Andric   if (D.isInvalidType())
2840b57cec5SDimitry Andric     return ExprError();
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric   if (getLangOpts().CPlusPlus) {
2870b57cec5SDimitry Andric     // Check that there are no default arguments (C++ only).
2880b57cec5SDimitry Andric     CheckExtraCXXDefaultArguments(D);
2890b57cec5SDimitry Andric   }
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric   return BuildCXXNamedCast(OpLoc, Kind, TInfo, E,
2920b57cec5SDimitry Andric                            SourceRange(LAngleBracketLoc, RAngleBracketLoc),
2930b57cec5SDimitry Andric                            SourceRange(LParenLoc, RParenLoc));
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric ExprResult
2970b57cec5SDimitry Andric Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
2980b57cec5SDimitry Andric                         TypeSourceInfo *DestTInfo, Expr *E,
2990b57cec5SDimitry Andric                         SourceRange AngleBrackets, SourceRange Parens) {
3000b57cec5SDimitry Andric   ExprResult Ex = E;
3010b57cec5SDimitry Andric   QualType DestType = DestTInfo->getType();
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric   // If the type is dependent, we won't do the semantic analysis now.
3040b57cec5SDimitry Andric   bool TypeDependent =
3050b57cec5SDimitry Andric       DestType->isDependentType() || Ex.get()->isTypeDependent();
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric   CastOperation Op(*this, DestType, E);
3080b57cec5SDimitry Andric   Op.OpRange = SourceRange(OpLoc, Parens.getEnd());
3090b57cec5SDimitry Andric   Op.DestRange = AngleBrackets;
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric   switch (Kind) {
3120b57cec5SDimitry Andric   default: llvm_unreachable("Unknown C++ cast!");
3130b57cec5SDimitry Andric 
3145ffd83dbSDimitry Andric   case tok::kw_addrspace_cast:
3155ffd83dbSDimitry Andric     if (!TypeDependent) {
3165ffd83dbSDimitry Andric       Op.CheckAddrspaceCast();
3175ffd83dbSDimitry Andric       if (Op.SrcExpr.isInvalid())
3185ffd83dbSDimitry Andric         return ExprError();
3195ffd83dbSDimitry Andric     }
3205ffd83dbSDimitry Andric     return Op.complete(CXXAddrspaceCastExpr::Create(
3215ffd83dbSDimitry Andric         Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
3225ffd83dbSDimitry Andric         DestTInfo, OpLoc, Parens.getEnd(), AngleBrackets));
3235ffd83dbSDimitry Andric 
3240b57cec5SDimitry Andric   case tok::kw_const_cast:
3250b57cec5SDimitry Andric     if (!TypeDependent) {
3260b57cec5SDimitry Andric       Op.CheckConstCast();
3270b57cec5SDimitry Andric       if (Op.SrcExpr.isInvalid())
3280b57cec5SDimitry Andric         return ExprError();
3290b57cec5SDimitry Andric       DiscardMisalignedMemberAddress(DestType.getTypePtr(), E);
3300b57cec5SDimitry Andric     }
3310b57cec5SDimitry Andric     return Op.complete(CXXConstCastExpr::Create(Context, Op.ResultType,
3320b57cec5SDimitry Andric                                   Op.ValueKind, Op.SrcExpr.get(), DestTInfo,
3330b57cec5SDimitry Andric                                                 OpLoc, Parens.getEnd(),
3340b57cec5SDimitry Andric                                                 AngleBrackets));
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric   case tok::kw_dynamic_cast: {
3370b57cec5SDimitry Andric     // dynamic_cast is not supported in C++ for OpenCL.
3380b57cec5SDimitry Andric     if (getLangOpts().OpenCLCPlusPlus) {
3390b57cec5SDimitry Andric       return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported)
3400b57cec5SDimitry Andric                        << "dynamic_cast");
3410b57cec5SDimitry Andric     }
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric     if (!TypeDependent) {
3440b57cec5SDimitry Andric       Op.CheckDynamicCast();
3450b57cec5SDimitry Andric       if (Op.SrcExpr.isInvalid())
3460b57cec5SDimitry Andric         return ExprError();
3470b57cec5SDimitry Andric     }
3480b57cec5SDimitry Andric     return Op.complete(CXXDynamicCastExpr::Create(Context, Op.ResultType,
3490b57cec5SDimitry Andric                                     Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
3500b57cec5SDimitry Andric                                                   &Op.BasePath, DestTInfo,
3510b57cec5SDimitry Andric                                                   OpLoc, Parens.getEnd(),
3520b57cec5SDimitry Andric                                                   AngleBrackets));
3530b57cec5SDimitry Andric   }
3540b57cec5SDimitry Andric   case tok::kw_reinterpret_cast: {
3550b57cec5SDimitry Andric     if (!TypeDependent) {
3560b57cec5SDimitry Andric       Op.CheckReinterpretCast();
3570b57cec5SDimitry Andric       if (Op.SrcExpr.isInvalid())
3580b57cec5SDimitry Andric         return ExprError();
3590b57cec5SDimitry Andric       DiscardMisalignedMemberAddress(DestType.getTypePtr(), E);
3600b57cec5SDimitry Andric     }
3610b57cec5SDimitry Andric     return Op.complete(CXXReinterpretCastExpr::Create(Context, Op.ResultType,
3620b57cec5SDimitry Andric                                     Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
3630b57cec5SDimitry Andric                                                       nullptr, DestTInfo, OpLoc,
3640b57cec5SDimitry Andric                                                       Parens.getEnd(),
3650b57cec5SDimitry Andric                                                       AngleBrackets));
3660b57cec5SDimitry Andric   }
3670b57cec5SDimitry Andric   case tok::kw_static_cast: {
3680b57cec5SDimitry Andric     if (!TypeDependent) {
3690b57cec5SDimitry Andric       Op.CheckStaticCast();
3700b57cec5SDimitry Andric       if (Op.SrcExpr.isInvalid())
3710b57cec5SDimitry Andric         return ExprError();
3720b57cec5SDimitry Andric       DiscardMisalignedMemberAddress(DestType.getTypePtr(), E);
3730b57cec5SDimitry Andric     }
3740b57cec5SDimitry Andric 
375e8d8bef9SDimitry Andric     return Op.complete(CXXStaticCastExpr::Create(
376e8d8bef9SDimitry Andric         Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
377e8d8bef9SDimitry Andric         &Op.BasePath, DestTInfo, CurFPFeatureOverrides(), OpLoc,
378e8d8bef9SDimitry Andric         Parens.getEnd(), AngleBrackets));
3790b57cec5SDimitry Andric   }
3800b57cec5SDimitry Andric   }
3810b57cec5SDimitry Andric }
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric ExprResult Sema::ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &D,
3840b57cec5SDimitry Andric                                          ExprResult Operand,
3850b57cec5SDimitry Andric                                          SourceLocation RParenLoc) {
3860b57cec5SDimitry Andric   assert(!D.isInvalidType());
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   TypeSourceInfo *TInfo = GetTypeForDeclaratorCast(D, Operand.get()->getType());
3890b57cec5SDimitry Andric   if (D.isInvalidType())
3900b57cec5SDimitry Andric     return ExprError();
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric   return BuildBuiltinBitCastExpr(KWLoc, TInfo, Operand.get(), RParenLoc);
3930b57cec5SDimitry Andric }
3940b57cec5SDimitry Andric 
3950b57cec5SDimitry Andric ExprResult Sema::BuildBuiltinBitCastExpr(SourceLocation KWLoc,
3960b57cec5SDimitry Andric                                          TypeSourceInfo *TSI, Expr *Operand,
3970b57cec5SDimitry Andric                                          SourceLocation RParenLoc) {
3980b57cec5SDimitry Andric   CastOperation Op(*this, TSI->getType(), Operand);
3990b57cec5SDimitry Andric   Op.OpRange = SourceRange(KWLoc, RParenLoc);
4000b57cec5SDimitry Andric   TypeLoc TL = TSI->getTypeLoc();
4010b57cec5SDimitry Andric   Op.DestRange = SourceRange(TL.getBeginLoc(), TL.getEndLoc());
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric   if (!Operand->isTypeDependent() && !TSI->getType()->isDependentType()) {
4040b57cec5SDimitry Andric     Op.CheckBuiltinBitCast();
4050b57cec5SDimitry Andric     if (Op.SrcExpr.isInvalid())
4060b57cec5SDimitry Andric       return ExprError();
4070b57cec5SDimitry Andric   }
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric   BuiltinBitCastExpr *BCE =
4100b57cec5SDimitry Andric       new (Context) BuiltinBitCastExpr(Op.ResultType, Op.ValueKind, Op.Kind,
4110b57cec5SDimitry Andric                                        Op.SrcExpr.get(), TSI, KWLoc, RParenLoc);
4120b57cec5SDimitry Andric   return Op.complete(BCE);
4130b57cec5SDimitry Andric }
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric /// Try to diagnose a failed overloaded cast.  Returns true if
4160b57cec5SDimitry Andric /// diagnostics were emitted.
4170b57cec5SDimitry Andric static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT,
4180b57cec5SDimitry Andric                                       SourceRange range, Expr *src,
4190b57cec5SDimitry Andric                                       QualType destType,
4200b57cec5SDimitry Andric                                       bool listInitialization) {
4210b57cec5SDimitry Andric   switch (CT) {
4220b57cec5SDimitry Andric   // These cast kinds don't consider user-defined conversions.
4230b57cec5SDimitry Andric   case CT_Const:
4240b57cec5SDimitry Andric   case CT_Reinterpret:
4250b57cec5SDimitry Andric   case CT_Dynamic:
4265ffd83dbSDimitry Andric   case CT_Addrspace:
4270b57cec5SDimitry Andric     return false;
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric   // These do.
4300b57cec5SDimitry Andric   case CT_Static:
4310b57cec5SDimitry Andric   case CT_CStyle:
4320b57cec5SDimitry Andric   case CT_Functional:
4330b57cec5SDimitry Andric     break;
4340b57cec5SDimitry Andric   }
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   QualType srcType = src->getType();
4370b57cec5SDimitry Andric   if (!destType->isRecordType() && !srcType->isRecordType())
4380b57cec5SDimitry Andric     return false;
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric   InitializedEntity entity = InitializedEntity::InitializeTemporary(destType);
4410b57cec5SDimitry Andric   InitializationKind initKind
4420b57cec5SDimitry Andric     = (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(),
4430b57cec5SDimitry Andric                                                       range, listInitialization)
4440b57cec5SDimitry Andric     : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range,
4450b57cec5SDimitry Andric                                                              listInitialization)
4460b57cec5SDimitry Andric     : InitializationKind::CreateCast(/*type range?*/ range);
4470b57cec5SDimitry Andric   InitializationSequence sequence(S, entity, initKind, src);
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric   assert(sequence.Failed() && "initialization succeeded on second try?");
4500b57cec5SDimitry Andric   switch (sequence.getFailureKind()) {
4510b57cec5SDimitry Andric   default: return false;
4520b57cec5SDimitry Andric 
45306c3fb27SDimitry Andric   case InitializationSequence::FK_ParenthesizedListInitFailed:
45406c3fb27SDimitry Andric     // In C++20, if the underlying destination type is a RecordType, Clang
45506c3fb27SDimitry Andric     // attempts to perform parentesized aggregate initialization if constructor
45606c3fb27SDimitry Andric     // overload fails:
45706c3fb27SDimitry Andric     //
45806c3fb27SDimitry Andric     // C++20 [expr.static.cast]p4:
45906c3fb27SDimitry Andric     //   An expression E can be explicitly converted to a type T...if overload
46006c3fb27SDimitry Andric     //   resolution for a direct-initialization...would find at least one viable
46106c3fb27SDimitry Andric     //   function ([over.match.viable]), or if T is an aggregate type having a
46206c3fb27SDimitry Andric     //   first element X and there is an implicit conversion sequence from E to
46306c3fb27SDimitry Andric     //   the type of X.
46406c3fb27SDimitry Andric     //
46506c3fb27SDimitry Andric     // If that fails, then we'll generate the diagnostics from the failed
46606c3fb27SDimitry Andric     // previous constructor overload attempt. Array initialization, however, is
46706c3fb27SDimitry Andric     // not done after attempting constructor overloading, so we exit as there
46806c3fb27SDimitry Andric     // won't be a failed overload result.
46906c3fb27SDimitry Andric     if (destType->isArrayType())
47006c3fb27SDimitry Andric       return false;
47106c3fb27SDimitry Andric     break;
4720b57cec5SDimitry Andric   case InitializationSequence::FK_ConstructorOverloadFailed:
4730b57cec5SDimitry Andric   case InitializationSequence::FK_UserConversionOverloadFailed:
4740b57cec5SDimitry Andric     break;
4750b57cec5SDimitry Andric   }
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   OverloadCandidateSet &candidates = sequence.getFailedCandidateSet();
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric   unsigned msg = 0;
4800b57cec5SDimitry Andric   OverloadCandidateDisplayKind howManyCandidates = OCD_AllCandidates;
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric   switch (sequence.getFailedOverloadResult()) {
4830b57cec5SDimitry Andric   case OR_Success: llvm_unreachable("successful failed overload");
4840b57cec5SDimitry Andric   case OR_No_Viable_Function:
4850b57cec5SDimitry Andric     if (candidates.empty())
4860b57cec5SDimitry Andric       msg = diag::err_ovl_no_conversion_in_cast;
4870b57cec5SDimitry Andric     else
4880b57cec5SDimitry Andric       msg = diag::err_ovl_no_viable_conversion_in_cast;
4890b57cec5SDimitry Andric     howManyCandidates = OCD_AllCandidates;
4900b57cec5SDimitry Andric     break;
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric   case OR_Ambiguous:
4930b57cec5SDimitry Andric     msg = diag::err_ovl_ambiguous_conversion_in_cast;
494480093f4SDimitry Andric     howManyCandidates = OCD_AmbiguousCandidates;
4950b57cec5SDimitry Andric     break;
4960b57cec5SDimitry Andric 
497*0fca6ea1SDimitry Andric   case OR_Deleted: {
498*0fca6ea1SDimitry Andric     OverloadCandidateSet::iterator Best;
499*0fca6ea1SDimitry Andric     [[maybe_unused]] OverloadingResult Res =
500*0fca6ea1SDimitry Andric         candidates.BestViableFunction(S, range.getBegin(), Best);
501*0fca6ea1SDimitry Andric     assert(Res == OR_Deleted && "Inconsistent overload resolution");
502*0fca6ea1SDimitry Andric 
503*0fca6ea1SDimitry Andric     StringLiteral *Msg = Best->Function->getDeletedMessage();
504*0fca6ea1SDimitry Andric     candidates.NoteCandidates(
505*0fca6ea1SDimitry Andric         PartialDiagnosticAt(range.getBegin(),
506*0fca6ea1SDimitry Andric                             S.PDiag(diag::err_ovl_deleted_conversion_in_cast)
507*0fca6ea1SDimitry Andric                                 << CT << srcType << destType << (Msg != nullptr)
508*0fca6ea1SDimitry Andric                                 << (Msg ? Msg->getString() : StringRef())
509*0fca6ea1SDimitry Andric                                 << range << src->getSourceRange()),
510*0fca6ea1SDimitry Andric         S, OCD_ViableCandidates, src);
511*0fca6ea1SDimitry Andric     return true;
512*0fca6ea1SDimitry Andric   }
5130b57cec5SDimitry Andric   }
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric   candidates.NoteCandidates(
5160b57cec5SDimitry Andric       PartialDiagnosticAt(range.getBegin(),
5170b57cec5SDimitry Andric                           S.PDiag(msg) << CT << srcType << destType << range
5180b57cec5SDimitry Andric                                        << src->getSourceRange()),
5190b57cec5SDimitry Andric       S, howManyCandidates, src);
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric   return true;
5220b57cec5SDimitry Andric }
5230b57cec5SDimitry Andric 
5240b57cec5SDimitry Andric /// Diagnose a failed cast.
5250b57cec5SDimitry Andric static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType,
5260b57cec5SDimitry Andric                             SourceRange opRange, Expr *src, QualType destType,
5270b57cec5SDimitry Andric                             bool listInitialization) {
5280b57cec5SDimitry Andric   if (msg == diag::err_bad_cxx_cast_generic &&
5290b57cec5SDimitry Andric       tryDiagnoseOverloadedCast(S, castType, opRange, src, destType,
5300b57cec5SDimitry Andric                                 listInitialization))
5310b57cec5SDimitry Andric     return;
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric   S.Diag(opRange.getBegin(), msg) << castType
5340b57cec5SDimitry Andric     << src->getType() << destType << opRange << src->getSourceRange();
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric   // Detect if both types are (ptr to) class, and note any incompleteness.
5370b57cec5SDimitry Andric   int DifferentPtrness = 0;
5380b57cec5SDimitry Andric   QualType From = destType;
5390b57cec5SDimitry Andric   if (auto Ptr = From->getAs<PointerType>()) {
5400b57cec5SDimitry Andric     From = Ptr->getPointeeType();
5410b57cec5SDimitry Andric     DifferentPtrness++;
5420b57cec5SDimitry Andric   }
5430b57cec5SDimitry Andric   QualType To = src->getType();
5440b57cec5SDimitry Andric   if (auto Ptr = To->getAs<PointerType>()) {
5450b57cec5SDimitry Andric     To = Ptr->getPointeeType();
5460b57cec5SDimitry Andric     DifferentPtrness--;
5470b57cec5SDimitry Andric   }
5480b57cec5SDimitry Andric   if (!DifferentPtrness) {
5490b57cec5SDimitry Andric     auto RecFrom = From->getAs<RecordType>();
5500b57cec5SDimitry Andric     auto RecTo = To->getAs<RecordType>();
5510b57cec5SDimitry Andric     if (RecFrom && RecTo) {
5520b57cec5SDimitry Andric       auto DeclFrom = RecFrom->getAsCXXRecordDecl();
5530b57cec5SDimitry Andric       if (!DeclFrom->isCompleteDefinition())
554e8d8bef9SDimitry Andric         S.Diag(DeclFrom->getLocation(), diag::note_type_incomplete) << DeclFrom;
5550b57cec5SDimitry Andric       auto DeclTo = RecTo->getAsCXXRecordDecl();
5560b57cec5SDimitry Andric       if (!DeclTo->isCompleteDefinition())
557e8d8bef9SDimitry Andric         S.Diag(DeclTo->getLocation(), diag::note_type_incomplete) << DeclTo;
5580b57cec5SDimitry Andric     }
5590b57cec5SDimitry Andric   }
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric namespace {
5630b57cec5SDimitry Andric /// The kind of unwrapping we did when determining whether a conversion casts
5640b57cec5SDimitry Andric /// away constness.
5650b57cec5SDimitry Andric enum CastAwayConstnessKind {
5660b57cec5SDimitry Andric   /// The conversion does not cast away constness.
5670b57cec5SDimitry Andric   CACK_None = 0,
5680b57cec5SDimitry Andric   /// We unwrapped similar types.
5690b57cec5SDimitry Andric   CACK_Similar = 1,
5700b57cec5SDimitry Andric   /// We unwrapped dissimilar types with similar representations (eg, a pointer
5710b57cec5SDimitry Andric   /// versus an Objective-C object pointer).
5720b57cec5SDimitry Andric   CACK_SimilarKind = 2,
5730b57cec5SDimitry Andric   /// We unwrapped representationally-unrelated types, such as a pointer versus
5740b57cec5SDimitry Andric   /// a pointer-to-member.
5750b57cec5SDimitry Andric   CACK_Incoherent = 3,
5760b57cec5SDimitry Andric };
5770b57cec5SDimitry Andric }
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric /// Unwrap one level of types for CastsAwayConstness.
5800b57cec5SDimitry Andric ///
5810b57cec5SDimitry Andric /// Like Sema::UnwrapSimilarTypes, this removes one level of indirection from
5820b57cec5SDimitry Andric /// both types, provided that they're both pointer-like or array-like. Unlike
5830b57cec5SDimitry Andric /// the Sema function, doesn't care if the unwrapped pieces are related.
5840b57cec5SDimitry Andric ///
5850b57cec5SDimitry Andric /// This function may remove additional levels as necessary for correctness:
5860b57cec5SDimitry Andric /// the resulting T1 is unwrapped sufficiently that it is never an array type,
5870b57cec5SDimitry Andric /// so that its qualifiers can be directly compared to those of T2 (which will
5880b57cec5SDimitry Andric /// have the combined set of qualifiers from all indermediate levels of T2),
5890b57cec5SDimitry Andric /// as (effectively) required by [expr.const.cast]p7 replacing T1's qualifiers
5900b57cec5SDimitry Andric /// with those from T2.
5910b57cec5SDimitry Andric static CastAwayConstnessKind
5920b57cec5SDimitry Andric unwrapCastAwayConstnessLevel(ASTContext &Context, QualType &T1, QualType &T2) {
5930b57cec5SDimitry Andric   enum { None, Ptr, MemPtr, BlockPtr, Array };
5940b57cec5SDimitry Andric   auto Classify = [](QualType T) {
5950b57cec5SDimitry Andric     if (T->isAnyPointerType()) return Ptr;
5960b57cec5SDimitry Andric     if (T->isMemberPointerType()) return MemPtr;
5970b57cec5SDimitry Andric     if (T->isBlockPointerType()) return BlockPtr;
5980b57cec5SDimitry Andric     // We somewhat-arbitrarily don't look through VLA types here. This is at
5990b57cec5SDimitry Andric     // least consistent with the behavior of UnwrapSimilarTypes.
6000b57cec5SDimitry Andric     if (T->isConstantArrayType() || T->isIncompleteArrayType()) return Array;
6010b57cec5SDimitry Andric     return None;
6020b57cec5SDimitry Andric   };
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric   auto Unwrap = [&](QualType T) {
6050b57cec5SDimitry Andric     if (auto *AT = Context.getAsArrayType(T))
6060b57cec5SDimitry Andric       return AT->getElementType();
6070b57cec5SDimitry Andric     return T->getPointeeType();
6080b57cec5SDimitry Andric   };
6090b57cec5SDimitry Andric 
6100b57cec5SDimitry Andric   CastAwayConstnessKind Kind;
6110b57cec5SDimitry Andric 
6120b57cec5SDimitry Andric   if (T2->isReferenceType()) {
6130b57cec5SDimitry Andric     // Special case: if the destination type is a reference type, unwrap it as
6140b57cec5SDimitry Andric     // the first level. (The source will have been an lvalue expression in this
6150b57cec5SDimitry Andric     // case, so there is no corresponding "reference to" in T1 to remove.) This
6160b57cec5SDimitry Andric     // simulates removing a "pointer to" from both sides.
6170b57cec5SDimitry Andric     T2 = T2->getPointeeType();
6180b57cec5SDimitry Andric     Kind = CastAwayConstnessKind::CACK_Similar;
6190b57cec5SDimitry Andric   } else if (Context.UnwrapSimilarTypes(T1, T2)) {
6200b57cec5SDimitry Andric     Kind = CastAwayConstnessKind::CACK_Similar;
6210b57cec5SDimitry Andric   } else {
6220b57cec5SDimitry Andric     // Try unwrapping mismatching levels.
6230b57cec5SDimitry Andric     int T1Class = Classify(T1);
6240b57cec5SDimitry Andric     if (T1Class == None)
6250b57cec5SDimitry Andric       return CastAwayConstnessKind::CACK_None;
6260b57cec5SDimitry Andric 
6270b57cec5SDimitry Andric     int T2Class = Classify(T2);
6280b57cec5SDimitry Andric     if (T2Class == None)
6290b57cec5SDimitry Andric       return CastAwayConstnessKind::CACK_None;
6300b57cec5SDimitry Andric 
6310b57cec5SDimitry Andric     T1 = Unwrap(T1);
6320b57cec5SDimitry Andric     T2 = Unwrap(T2);
6330b57cec5SDimitry Andric     Kind = T1Class == T2Class ? CastAwayConstnessKind::CACK_SimilarKind
6340b57cec5SDimitry Andric                               : CastAwayConstnessKind::CACK_Incoherent;
6350b57cec5SDimitry Andric   }
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric   // We've unwrapped at least one level. If the resulting T1 is a (possibly
6380b57cec5SDimitry Andric   // multidimensional) array type, any qualifier on any matching layer of
6390b57cec5SDimitry Andric   // T2 is considered to correspond to T1. Decompose down to the element
6400b57cec5SDimitry Andric   // type of T1 so that we can compare properly.
6410b57cec5SDimitry Andric   while (true) {
6420b57cec5SDimitry Andric     Context.UnwrapSimilarArrayTypes(T1, T2);
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric     if (Classify(T1) != Array)
6450b57cec5SDimitry Andric       break;
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric     auto T2Class = Classify(T2);
6480b57cec5SDimitry Andric     if (T2Class == None)
6490b57cec5SDimitry Andric       break;
6500b57cec5SDimitry Andric 
6510b57cec5SDimitry Andric     if (T2Class != Array)
6520b57cec5SDimitry Andric       Kind = CastAwayConstnessKind::CACK_Incoherent;
6530b57cec5SDimitry Andric     else if (Kind != CastAwayConstnessKind::CACK_Incoherent)
6540b57cec5SDimitry Andric       Kind = CastAwayConstnessKind::CACK_SimilarKind;
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric     T1 = Unwrap(T1);
6570b57cec5SDimitry Andric     T2 = Unwrap(T2).withCVRQualifiers(T2.getCVRQualifiers());
6580b57cec5SDimitry Andric   }
6590b57cec5SDimitry Andric 
6600b57cec5SDimitry Andric   return Kind;
6610b57cec5SDimitry Andric }
6620b57cec5SDimitry Andric 
6630b57cec5SDimitry Andric /// Check if the pointer conversion from SrcType to DestType casts away
6640b57cec5SDimitry Andric /// constness as defined in C++ [expr.const.cast]. This is used by the cast
6650b57cec5SDimitry Andric /// checkers. Both arguments must denote pointer (possibly to member) types.
6660b57cec5SDimitry Andric ///
6670b57cec5SDimitry Andric /// \param CheckCVR Whether to check for const/volatile/restrict qualifiers.
6680b57cec5SDimitry Andric /// \param CheckObjCLifetime Whether to check Objective-C lifetime qualifiers.
6690b57cec5SDimitry Andric static CastAwayConstnessKind
6700b57cec5SDimitry Andric CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType,
6710b57cec5SDimitry Andric                    bool CheckCVR, bool CheckObjCLifetime,
6720b57cec5SDimitry Andric                    QualType *TheOffendingSrcType = nullptr,
6730b57cec5SDimitry Andric                    QualType *TheOffendingDestType = nullptr,
6740b57cec5SDimitry Andric                    Qualifiers *CastAwayQualifiers = nullptr) {
6750b57cec5SDimitry Andric   // If the only checking we care about is for Objective-C lifetime qualifiers,
6760b57cec5SDimitry Andric   // and we're not in ObjC mode, there's nothing to check.
6770b57cec5SDimitry Andric   if (!CheckCVR && CheckObjCLifetime && !Self.Context.getLangOpts().ObjC)
6780b57cec5SDimitry Andric     return CastAwayConstnessKind::CACK_None;
6790b57cec5SDimitry Andric 
6800b57cec5SDimitry Andric   if (!DestType->isReferenceType()) {
6810b57cec5SDimitry Andric     assert((SrcType->isAnyPointerType() || SrcType->isMemberPointerType() ||
6820b57cec5SDimitry Andric             SrcType->isBlockPointerType()) &&
6830b57cec5SDimitry Andric            "Source type is not pointer or pointer to member.");
6840b57cec5SDimitry Andric     assert((DestType->isAnyPointerType() || DestType->isMemberPointerType() ||
6850b57cec5SDimitry Andric             DestType->isBlockPointerType()) &&
6860b57cec5SDimitry Andric            "Destination type is not pointer or pointer to member.");
6870b57cec5SDimitry Andric   }
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric   QualType UnwrappedSrcType = Self.Context.getCanonicalType(SrcType),
6900b57cec5SDimitry Andric            UnwrappedDestType = Self.Context.getCanonicalType(DestType);
6910b57cec5SDimitry Andric 
6920b57cec5SDimitry Andric   // Find the qualifiers. We only care about cvr-qualifiers for the
6930b57cec5SDimitry Andric   // purpose of this check, because other qualifiers (address spaces,
6940b57cec5SDimitry Andric   // Objective-C GC, etc.) are part of the type's identity.
6950b57cec5SDimitry Andric   QualType PrevUnwrappedSrcType = UnwrappedSrcType;
6960b57cec5SDimitry Andric   QualType PrevUnwrappedDestType = UnwrappedDestType;
6970b57cec5SDimitry Andric   auto WorstKind = CastAwayConstnessKind::CACK_Similar;
6980b57cec5SDimitry Andric   bool AllConstSoFar = true;
6990b57cec5SDimitry Andric   while (auto Kind = unwrapCastAwayConstnessLevel(
7000b57cec5SDimitry Andric              Self.Context, UnwrappedSrcType, UnwrappedDestType)) {
7010b57cec5SDimitry Andric     // Track the worst kind of unwrap we needed to do before we found a
7020b57cec5SDimitry Andric     // problem.
7030b57cec5SDimitry Andric     if (Kind > WorstKind)
7040b57cec5SDimitry Andric       WorstKind = Kind;
7050b57cec5SDimitry Andric 
7060b57cec5SDimitry Andric     // Determine the relevant qualifiers at this level.
7070b57cec5SDimitry Andric     Qualifiers SrcQuals, DestQuals;
7080b57cec5SDimitry Andric     Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals);
7090b57cec5SDimitry Andric     Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals);
7100b57cec5SDimitry Andric 
7110b57cec5SDimitry Andric     // We do not meaningfully track object const-ness of Objective-C object
7120b57cec5SDimitry Andric     // types. Remove const from the source type if either the source or
7130b57cec5SDimitry Andric     // the destination is an Objective-C object type.
7140b57cec5SDimitry Andric     if (UnwrappedSrcType->isObjCObjectType() ||
7150b57cec5SDimitry Andric         UnwrappedDestType->isObjCObjectType())
7160b57cec5SDimitry Andric       SrcQuals.removeConst();
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric     if (CheckCVR) {
7190b57cec5SDimitry Andric       Qualifiers SrcCvrQuals =
7200b57cec5SDimitry Andric           Qualifiers::fromCVRMask(SrcQuals.getCVRQualifiers());
7210b57cec5SDimitry Andric       Qualifiers DestCvrQuals =
7220b57cec5SDimitry Andric           Qualifiers::fromCVRMask(DestQuals.getCVRQualifiers());
7230b57cec5SDimitry Andric 
7240b57cec5SDimitry Andric       if (SrcCvrQuals != DestCvrQuals) {
7250b57cec5SDimitry Andric         if (CastAwayQualifiers)
7260b57cec5SDimitry Andric           *CastAwayQualifiers = SrcCvrQuals - DestCvrQuals;
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric         // If we removed a cvr-qualifier, this is casting away 'constness'.
7290b57cec5SDimitry Andric         if (!DestCvrQuals.compatiblyIncludes(SrcCvrQuals)) {
7300b57cec5SDimitry Andric           if (TheOffendingSrcType)
7310b57cec5SDimitry Andric             *TheOffendingSrcType = PrevUnwrappedSrcType;
7320b57cec5SDimitry Andric           if (TheOffendingDestType)
7330b57cec5SDimitry Andric             *TheOffendingDestType = PrevUnwrappedDestType;
7340b57cec5SDimitry Andric           return WorstKind;
7350b57cec5SDimitry Andric         }
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric         // If any prior level was not 'const', this is also casting away
7380b57cec5SDimitry Andric         // 'constness'. We noted the outermost type missing a 'const' already.
7390b57cec5SDimitry Andric         if (!AllConstSoFar)
7400b57cec5SDimitry Andric           return WorstKind;
7410b57cec5SDimitry Andric       }
7420b57cec5SDimitry Andric     }
7430b57cec5SDimitry Andric 
7440b57cec5SDimitry Andric     if (CheckObjCLifetime &&
7450b57cec5SDimitry Andric         !DestQuals.compatiblyIncludesObjCLifetime(SrcQuals))
7460b57cec5SDimitry Andric       return WorstKind;
7470b57cec5SDimitry Andric 
7480b57cec5SDimitry Andric     // If we found our first non-const-qualified type, this may be the place
7490b57cec5SDimitry Andric     // where things start to go wrong.
7500b57cec5SDimitry Andric     if (AllConstSoFar && !DestQuals.hasConst()) {
7510b57cec5SDimitry Andric       AllConstSoFar = false;
7520b57cec5SDimitry Andric       if (TheOffendingSrcType)
7530b57cec5SDimitry Andric         *TheOffendingSrcType = PrevUnwrappedSrcType;
7540b57cec5SDimitry Andric       if (TheOffendingDestType)
7550b57cec5SDimitry Andric         *TheOffendingDestType = PrevUnwrappedDestType;
7560b57cec5SDimitry Andric     }
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric     PrevUnwrappedSrcType = UnwrappedSrcType;
7590b57cec5SDimitry Andric     PrevUnwrappedDestType = UnwrappedDestType;
7600b57cec5SDimitry Andric   }
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric   return CastAwayConstnessKind::CACK_None;
7630b57cec5SDimitry Andric }
7640b57cec5SDimitry Andric 
7650b57cec5SDimitry Andric static TryCastResult getCastAwayConstnessCastKind(CastAwayConstnessKind CACK,
7660b57cec5SDimitry Andric                                                   unsigned &DiagID) {
7670b57cec5SDimitry Andric   switch (CACK) {
7680b57cec5SDimitry Andric   case CastAwayConstnessKind::CACK_None:
7690b57cec5SDimitry Andric     llvm_unreachable("did not cast away constness");
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric   case CastAwayConstnessKind::CACK_Similar:
7720b57cec5SDimitry Andric     // FIXME: Accept these as an extension too?
7730b57cec5SDimitry Andric   case CastAwayConstnessKind::CACK_SimilarKind:
7740b57cec5SDimitry Andric     DiagID = diag::err_bad_cxx_cast_qualifiers_away;
7750b57cec5SDimitry Andric     return TC_Failed;
7760b57cec5SDimitry Andric 
7770b57cec5SDimitry Andric   case CastAwayConstnessKind::CACK_Incoherent:
7780b57cec5SDimitry Andric     DiagID = diag::ext_bad_cxx_cast_qualifiers_away_incoherent;
7790b57cec5SDimitry Andric     return TC_Extension;
7800b57cec5SDimitry Andric   }
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric   llvm_unreachable("unexpected cast away constness kind");
7830b57cec5SDimitry Andric }
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric /// CheckDynamicCast - Check that a dynamic_cast\<DestType\>(SrcExpr) is valid.
7860b57cec5SDimitry Andric /// Refer to C++ 5.2.7 for details. Dynamic casts are used mostly for runtime-
7870b57cec5SDimitry Andric /// checked downcasts in class hierarchies.
7880b57cec5SDimitry Andric void CastOperation::CheckDynamicCast() {
7895ffd83dbSDimitry Andric   CheckNoDerefRAII NoderefCheck(*this);
7905ffd83dbSDimitry Andric 
791fe6060f1SDimitry Andric   if (ValueKind == VK_PRValue)
7920b57cec5SDimitry Andric     SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
7930b57cec5SDimitry Andric   else if (isPlaceholder())
7940b57cec5SDimitry Andric     SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
7950b57cec5SDimitry Andric   if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
7960b57cec5SDimitry Andric     return;
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric   QualType OrigSrcType = SrcExpr.get()->getType();
7990b57cec5SDimitry Andric   QualType DestType = Self.Context.getCanonicalType(this->DestType);
8000b57cec5SDimitry Andric 
8010b57cec5SDimitry Andric   // C++ 5.2.7p1: T shall be a pointer or reference to a complete class type,
8020b57cec5SDimitry Andric   //   or "pointer to cv void".
8030b57cec5SDimitry Andric 
8040b57cec5SDimitry Andric   QualType DestPointee;
8050b57cec5SDimitry Andric   const PointerType *DestPointer = DestType->getAs<PointerType>();
8060b57cec5SDimitry Andric   const ReferenceType *DestReference = nullptr;
8070b57cec5SDimitry Andric   if (DestPointer) {
8080b57cec5SDimitry Andric     DestPointee = DestPointer->getPointeeType();
8090b57cec5SDimitry Andric   } else if ((DestReference = DestType->getAs<ReferenceType>())) {
8100b57cec5SDimitry Andric     DestPointee = DestReference->getPointeeType();
8110b57cec5SDimitry Andric   } else {
8120b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
8130b57cec5SDimitry Andric       << this->DestType << DestRange;
8140b57cec5SDimitry Andric     SrcExpr = ExprError();
8150b57cec5SDimitry Andric     return;
8160b57cec5SDimitry Andric   }
8170b57cec5SDimitry Andric 
8180b57cec5SDimitry Andric   const RecordType *DestRecord = DestPointee->getAs<RecordType>();
8190b57cec5SDimitry Andric   if (DestPointee->isVoidType()) {
8200b57cec5SDimitry Andric     assert(DestPointer && "Reference to void is not possible");
8210b57cec5SDimitry Andric   } else if (DestRecord) {
8220b57cec5SDimitry Andric     if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee,
823480093f4SDimitry Andric                                  diag::err_bad_cast_incomplete,
8240b57cec5SDimitry Andric                                  DestRange)) {
8250b57cec5SDimitry Andric       SrcExpr = ExprError();
8260b57cec5SDimitry Andric       return;
8270b57cec5SDimitry Andric     }
8280b57cec5SDimitry Andric   } else {
8290b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
8300b57cec5SDimitry Andric       << DestPointee.getUnqualifiedType() << DestRange;
8310b57cec5SDimitry Andric     SrcExpr = ExprError();
8320b57cec5SDimitry Andric     return;
8330b57cec5SDimitry Andric   }
8340b57cec5SDimitry Andric 
8350b57cec5SDimitry Andric   // C++0x 5.2.7p2: If T is a pointer type, v shall be an rvalue of a pointer to
8360b57cec5SDimitry Andric   //   complete class type, [...]. If T is an lvalue reference type, v shall be
8370b57cec5SDimitry Andric   //   an lvalue of a complete class type, [...]. If T is an rvalue reference
8380b57cec5SDimitry Andric   //   type, v shall be an expression having a complete class type, [...]
8390b57cec5SDimitry Andric   QualType SrcType = Self.Context.getCanonicalType(OrigSrcType);
8400b57cec5SDimitry Andric   QualType SrcPointee;
8410b57cec5SDimitry Andric   if (DestPointer) {
8420b57cec5SDimitry Andric     if (const PointerType *SrcPointer = SrcType->getAs<PointerType>()) {
8430b57cec5SDimitry Andric       SrcPointee = SrcPointer->getPointeeType();
8440b57cec5SDimitry Andric     } else {
8450b57cec5SDimitry Andric       Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
846480093f4SDimitry Andric           << OrigSrcType << this->DestType << SrcExpr.get()->getSourceRange();
8470b57cec5SDimitry Andric       SrcExpr = ExprError();
8480b57cec5SDimitry Andric       return;
8490b57cec5SDimitry Andric     }
8500b57cec5SDimitry Andric   } else if (DestReference->isLValueReferenceType()) {
8510b57cec5SDimitry Andric     if (!SrcExpr.get()->isLValue()) {
8520b57cec5SDimitry Andric       Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
8530b57cec5SDimitry Andric         << CT_Dynamic << OrigSrcType << this->DestType << OpRange;
8540b57cec5SDimitry Andric     }
8550b57cec5SDimitry Andric     SrcPointee = SrcType;
8560b57cec5SDimitry Andric   } else {
8570b57cec5SDimitry Andric     // If we're dynamic_casting from a prvalue to an rvalue reference, we need
8580b57cec5SDimitry Andric     // to materialize the prvalue before we bind the reference to it.
859fe6060f1SDimitry Andric     if (SrcExpr.get()->isPRValue())
8600b57cec5SDimitry Andric       SrcExpr = Self.CreateMaterializeTemporaryExpr(
8610b57cec5SDimitry Andric           SrcType, SrcExpr.get(), /*IsLValueReference*/ false);
8620b57cec5SDimitry Andric     SrcPointee = SrcType;
8630b57cec5SDimitry Andric   }
8640b57cec5SDimitry Andric 
8650b57cec5SDimitry Andric   const RecordType *SrcRecord = SrcPointee->getAs<RecordType>();
8660b57cec5SDimitry Andric   if (SrcRecord) {
8670b57cec5SDimitry Andric     if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
868480093f4SDimitry Andric                                  diag::err_bad_cast_incomplete,
8690b57cec5SDimitry Andric                                  SrcExpr.get())) {
8700b57cec5SDimitry Andric       SrcExpr = ExprError();
8710b57cec5SDimitry Andric       return;
8720b57cec5SDimitry Andric     }
8730b57cec5SDimitry Andric   } else {
8740b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
8750b57cec5SDimitry Andric       << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();
8760b57cec5SDimitry Andric     SrcExpr = ExprError();
8770b57cec5SDimitry Andric     return;
8780b57cec5SDimitry Andric   }
8790b57cec5SDimitry Andric 
8800b57cec5SDimitry Andric   assert((DestPointer || DestReference) &&
8810b57cec5SDimitry Andric     "Bad destination non-ptr/ref slipped through.");
8820b57cec5SDimitry Andric   assert((DestRecord || DestPointee->isVoidType()) &&
8830b57cec5SDimitry Andric     "Bad destination pointee slipped through.");
8840b57cec5SDimitry Andric   assert(SrcRecord && "Bad source pointee slipped through.");
8850b57cec5SDimitry Andric 
8860b57cec5SDimitry Andric   // C++ 5.2.7p1: The dynamic_cast operator shall not cast away constness.
8870b57cec5SDimitry Andric   if (!DestPointee.isAtLeastAsQualifiedAs(SrcPointee)) {
8880b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away)
8890b57cec5SDimitry Andric       << CT_Dynamic << OrigSrcType << this->DestType << OpRange;
8900b57cec5SDimitry Andric     SrcExpr = ExprError();
8910b57cec5SDimitry Andric     return;
8920b57cec5SDimitry Andric   }
8930b57cec5SDimitry Andric 
8940b57cec5SDimitry Andric   // C++ 5.2.7p3: If the type of v is the same as the required result type,
8950b57cec5SDimitry Andric   //   [except for cv].
8960b57cec5SDimitry Andric   if (DestRecord == SrcRecord) {
8970b57cec5SDimitry Andric     Kind = CK_NoOp;
8980b57cec5SDimitry Andric     return;
8990b57cec5SDimitry Andric   }
9000b57cec5SDimitry Andric 
9010b57cec5SDimitry Andric   // C++ 5.2.7p5
9020b57cec5SDimitry Andric   // Upcasts are resolved statically.
9030b57cec5SDimitry Andric   if (DestRecord &&
9040b57cec5SDimitry Andric       Self.IsDerivedFrom(OpRange.getBegin(), SrcPointee, DestPointee)) {
9050b57cec5SDimitry Andric     if (Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,
9060b57cec5SDimitry Andric                                            OpRange.getBegin(), OpRange,
9070b57cec5SDimitry Andric                                            &BasePath)) {
9080b57cec5SDimitry Andric       SrcExpr = ExprError();
9090b57cec5SDimitry Andric       return;
9100b57cec5SDimitry Andric     }
9110b57cec5SDimitry Andric 
9120b57cec5SDimitry Andric     Kind = CK_DerivedToBase;
9130b57cec5SDimitry Andric     return;
9140b57cec5SDimitry Andric   }
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric   // C++ 5.2.7p6: Otherwise, v shall be [polymorphic].
9170b57cec5SDimitry Andric   const RecordDecl *SrcDecl = SrcRecord->getDecl()->getDefinition();
9180b57cec5SDimitry Andric   assert(SrcDecl && "Definition missing");
9190b57cec5SDimitry Andric   if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
9200b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
9210b57cec5SDimitry Andric       << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();
9220b57cec5SDimitry Andric     SrcExpr = ExprError();
9230b57cec5SDimitry Andric   }
9240b57cec5SDimitry Andric 
9250b57cec5SDimitry Andric   // dynamic_cast is not available with -fno-rtti.
9260b57cec5SDimitry Andric   // As an exception, dynamic_cast to void* is available because it doesn't
9270b57cec5SDimitry Andric   // use RTTI.
9280b57cec5SDimitry Andric   if (!Self.getLangOpts().RTTI && !DestPointee->isVoidType()) {
9290b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti);
9300b57cec5SDimitry Andric     SrcExpr = ExprError();
9310b57cec5SDimitry Andric     return;
9320b57cec5SDimitry Andric   }
9330b57cec5SDimitry Andric 
934e8d8bef9SDimitry Andric   // Warns when dynamic_cast is used with RTTI data disabled.
935e8d8bef9SDimitry Andric   if (!Self.getLangOpts().RTTIData) {
936e8d8bef9SDimitry Andric     bool MicrosoftABI =
937e8d8bef9SDimitry Andric         Self.getASTContext().getTargetInfo().getCXXABI().isMicrosoft();
938e8d8bef9SDimitry Andric     bool isClangCL = Self.getDiagnostics().getDiagnosticOptions().getFormat() ==
939e8d8bef9SDimitry Andric                      DiagnosticOptions::MSVC;
940e8d8bef9SDimitry Andric     if (MicrosoftABI || !DestPointee->isVoidType())
941e8d8bef9SDimitry Andric       Self.Diag(OpRange.getBegin(),
942e8d8bef9SDimitry Andric                 diag::warn_no_dynamic_cast_with_rtti_disabled)
943e8d8bef9SDimitry Andric           << isClangCL;
944e8d8bef9SDimitry Andric   }
945e8d8bef9SDimitry Andric 
9468a4dda33SDimitry Andric   // For a dynamic_cast to a final type, IR generation might emit a reference
9478a4dda33SDimitry Andric   // to the vtable.
9488a4dda33SDimitry Andric   if (DestRecord) {
9498a4dda33SDimitry Andric     auto *DestDecl = DestRecord->getAsCXXRecordDecl();
9508a4dda33SDimitry Andric     if (DestDecl->isEffectivelyFinal())
9518a4dda33SDimitry Andric       Self.MarkVTableUsed(OpRange.getBegin(), DestDecl);
9528a4dda33SDimitry Andric   }
9538a4dda33SDimitry Andric 
9540b57cec5SDimitry Andric   // Done. Everything else is run-time checks.
9550b57cec5SDimitry Andric   Kind = CK_Dynamic;
9560b57cec5SDimitry Andric }
9570b57cec5SDimitry Andric 
9580b57cec5SDimitry Andric /// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid.
9590b57cec5SDimitry Andric /// Refer to C++ 5.2.11 for details. const_cast is typically used in code
9600b57cec5SDimitry Andric /// like this:
9610b57cec5SDimitry Andric /// const char *str = "literal";
9620b57cec5SDimitry Andric /// legacy_function(const_cast\<char*\>(str));
9630b57cec5SDimitry Andric void CastOperation::CheckConstCast() {
9645ffd83dbSDimitry Andric   CheckNoDerefRAII NoderefCheck(*this);
9655ffd83dbSDimitry Andric 
966fe6060f1SDimitry Andric   if (ValueKind == VK_PRValue)
9670b57cec5SDimitry Andric     SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
9680b57cec5SDimitry Andric   else if (isPlaceholder())
9690b57cec5SDimitry Andric     SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
9700b57cec5SDimitry Andric   if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
9710b57cec5SDimitry Andric     return;
9720b57cec5SDimitry Andric 
9730b57cec5SDimitry Andric   unsigned msg = diag::err_bad_cxx_cast_generic;
9740b57cec5SDimitry Andric   auto TCR = TryConstCast(Self, SrcExpr, DestType, /*CStyle*/ false, msg);
9750b57cec5SDimitry Andric   if (TCR != TC_Success && msg != 0) {
9760b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), msg) << CT_Const
9770b57cec5SDimitry Andric       << SrcExpr.get()->getType() << DestType << OpRange;
9780b57cec5SDimitry Andric   }
9790b57cec5SDimitry Andric   if (!isValidCast(TCR))
9800b57cec5SDimitry Andric     SrcExpr = ExprError();
9810b57cec5SDimitry Andric }
9820b57cec5SDimitry Andric 
9835ffd83dbSDimitry Andric void CastOperation::CheckAddrspaceCast() {
9845ffd83dbSDimitry Andric   unsigned msg = diag::err_bad_cxx_cast_generic;
9855ffd83dbSDimitry Andric   auto TCR =
9865ffd83dbSDimitry Andric       TryAddressSpaceCast(Self, SrcExpr, DestType, /*CStyle*/ false, msg, Kind);
9875ffd83dbSDimitry Andric   if (TCR != TC_Success && msg != 0) {
9885ffd83dbSDimitry Andric     Self.Diag(OpRange.getBegin(), msg)
9895ffd83dbSDimitry Andric         << CT_Addrspace << SrcExpr.get()->getType() << DestType << OpRange;
9905ffd83dbSDimitry Andric   }
9915ffd83dbSDimitry Andric   if (!isValidCast(TCR))
9925ffd83dbSDimitry Andric     SrcExpr = ExprError();
9935ffd83dbSDimitry Andric }
9945ffd83dbSDimitry Andric 
9950b57cec5SDimitry Andric /// Check that a reinterpret_cast\<DestType\>(SrcExpr) is not used as upcast
9960b57cec5SDimitry Andric /// or downcast between respective pointers or references.
9970b57cec5SDimitry Andric static void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr,
9980b57cec5SDimitry Andric                                           QualType DestType,
9990b57cec5SDimitry Andric                                           SourceRange OpRange) {
10000b57cec5SDimitry Andric   QualType SrcType = SrcExpr->getType();
10010b57cec5SDimitry Andric   // When casting from pointer or reference, get pointee type; use original
10020b57cec5SDimitry Andric   // type otherwise.
10030b57cec5SDimitry Andric   const CXXRecordDecl *SrcPointeeRD = SrcType->getPointeeCXXRecordDecl();
10040b57cec5SDimitry Andric   const CXXRecordDecl *SrcRD =
10050b57cec5SDimitry Andric     SrcPointeeRD ? SrcPointeeRD : SrcType->getAsCXXRecordDecl();
10060b57cec5SDimitry Andric 
10070b57cec5SDimitry Andric   // Examining subobjects for records is only possible if the complete and
10080b57cec5SDimitry Andric   // valid definition is available.  Also, template instantiation is not
10090b57cec5SDimitry Andric   // allowed here.
10100b57cec5SDimitry Andric   if (!SrcRD || !SrcRD->isCompleteDefinition() || SrcRD->isInvalidDecl())
10110b57cec5SDimitry Andric     return;
10120b57cec5SDimitry Andric 
10130b57cec5SDimitry Andric   const CXXRecordDecl *DestRD = DestType->getPointeeCXXRecordDecl();
10140b57cec5SDimitry Andric 
10150b57cec5SDimitry Andric   if (!DestRD || !DestRD->isCompleteDefinition() || DestRD->isInvalidDecl())
10160b57cec5SDimitry Andric     return;
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric   enum {
10190b57cec5SDimitry Andric     ReinterpretUpcast,
10200b57cec5SDimitry Andric     ReinterpretDowncast
10210b57cec5SDimitry Andric   } ReinterpretKind;
10220b57cec5SDimitry Andric 
10230b57cec5SDimitry Andric   CXXBasePaths BasePaths;
10240b57cec5SDimitry Andric 
10250b57cec5SDimitry Andric   if (SrcRD->isDerivedFrom(DestRD, BasePaths))
10260b57cec5SDimitry Andric     ReinterpretKind = ReinterpretUpcast;
10270b57cec5SDimitry Andric   else if (DestRD->isDerivedFrom(SrcRD, BasePaths))
10280b57cec5SDimitry Andric     ReinterpretKind = ReinterpretDowncast;
10290b57cec5SDimitry Andric   else
10300b57cec5SDimitry Andric     return;
10310b57cec5SDimitry Andric 
10320b57cec5SDimitry Andric   bool VirtualBase = true;
10330b57cec5SDimitry Andric   bool NonZeroOffset = false;
10340b57cec5SDimitry Andric   for (CXXBasePaths::const_paths_iterator I = BasePaths.begin(),
10350b57cec5SDimitry Andric                                           E = BasePaths.end();
10360b57cec5SDimitry Andric        I != E; ++I) {
10370b57cec5SDimitry Andric     const CXXBasePath &Path = *I;
10380b57cec5SDimitry Andric     CharUnits Offset = CharUnits::Zero();
10390b57cec5SDimitry Andric     bool IsVirtual = false;
10400b57cec5SDimitry Andric     for (CXXBasePath::const_iterator IElem = Path.begin(), EElem = Path.end();
10410b57cec5SDimitry Andric          IElem != EElem; ++IElem) {
10420b57cec5SDimitry Andric       IsVirtual = IElem->Base->isVirtual();
10430b57cec5SDimitry Andric       if (IsVirtual)
10440b57cec5SDimitry Andric         break;
10450b57cec5SDimitry Andric       const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl();
10460b57cec5SDimitry Andric       assert(BaseRD && "Base type should be a valid unqualified class type");
10470b57cec5SDimitry Andric       // Don't check if any base has invalid declaration or has no definition
10480b57cec5SDimitry Andric       // since it has no layout info.
10490b57cec5SDimitry Andric       const CXXRecordDecl *Class = IElem->Class,
10500b57cec5SDimitry Andric                           *ClassDefinition = Class->getDefinition();
10510b57cec5SDimitry Andric       if (Class->isInvalidDecl() || !ClassDefinition ||
10520b57cec5SDimitry Andric           !ClassDefinition->isCompleteDefinition())
10530b57cec5SDimitry Andric         return;
10540b57cec5SDimitry Andric 
10550b57cec5SDimitry Andric       const ASTRecordLayout &DerivedLayout =
10560b57cec5SDimitry Andric           Self.Context.getASTRecordLayout(Class);
10570b57cec5SDimitry Andric       Offset += DerivedLayout.getBaseClassOffset(BaseRD);
10580b57cec5SDimitry Andric     }
10590b57cec5SDimitry Andric     if (!IsVirtual) {
10600b57cec5SDimitry Andric       // Don't warn if any path is a non-virtually derived base at offset zero.
10610b57cec5SDimitry Andric       if (Offset.isZero())
10620b57cec5SDimitry Andric         return;
10630b57cec5SDimitry Andric       // Offset makes sense only for non-virtual bases.
10640b57cec5SDimitry Andric       else
10650b57cec5SDimitry Andric         NonZeroOffset = true;
10660b57cec5SDimitry Andric     }
10670b57cec5SDimitry Andric     VirtualBase = VirtualBase && IsVirtual;
10680b57cec5SDimitry Andric   }
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric   (void) NonZeroOffset; // Silence set but not used warning.
10710b57cec5SDimitry Andric   assert((VirtualBase || NonZeroOffset) &&
10720b57cec5SDimitry Andric          "Should have returned if has non-virtual base with zero offset");
10730b57cec5SDimitry Andric 
10740b57cec5SDimitry Andric   QualType BaseType =
10750b57cec5SDimitry Andric       ReinterpretKind == ReinterpretUpcast? DestType : SrcType;
10760b57cec5SDimitry Andric   QualType DerivedType =
10770b57cec5SDimitry Andric       ReinterpretKind == ReinterpretUpcast? SrcType : DestType;
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric   SourceLocation BeginLoc = OpRange.getBegin();
10800b57cec5SDimitry Andric   Self.Diag(BeginLoc, diag::warn_reinterpret_different_from_static)
10810b57cec5SDimitry Andric     << DerivedType << BaseType << !VirtualBase << int(ReinterpretKind)
10820b57cec5SDimitry Andric     << OpRange;
10830b57cec5SDimitry Andric   Self.Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static)
10840b57cec5SDimitry Andric     << int(ReinterpretKind)
10850b57cec5SDimitry Andric     << FixItHint::CreateReplacement(BeginLoc, "static_cast");
10860b57cec5SDimitry Andric }
10870b57cec5SDimitry Andric 
1088fe6060f1SDimitry Andric static bool argTypeIsABIEquivalent(QualType SrcType, QualType DestType,
1089fe6060f1SDimitry Andric                                    ASTContext &Context) {
1090fe6060f1SDimitry Andric   if (SrcType->isPointerType() && DestType->isPointerType())
1091fe6060f1SDimitry Andric     return true;
1092fe6060f1SDimitry Andric 
1093fe6060f1SDimitry Andric   // Allow integral type mismatch if their size are equal.
1094*0fca6ea1SDimitry Andric   if ((SrcType->isIntegralType(Context) || SrcType->isEnumeralType()) &&
1095*0fca6ea1SDimitry Andric       (DestType->isIntegralType(Context) || DestType->isEnumeralType()))
1096*0fca6ea1SDimitry Andric     if (Context.getTypeSizeInChars(SrcType) ==
1097*0fca6ea1SDimitry Andric         Context.getTypeSizeInChars(DestType))
1098fe6060f1SDimitry Andric       return true;
1099fe6060f1SDimitry Andric 
1100fe6060f1SDimitry Andric   return Context.hasSameUnqualifiedType(SrcType, DestType);
1101fe6060f1SDimitry Andric }
1102fe6060f1SDimitry Andric 
1103bdd1243dSDimitry Andric static unsigned int checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr,
1104fe6060f1SDimitry Andric                                           QualType DestType) {
1105bdd1243dSDimitry Andric   unsigned int DiagID = 0;
1106bdd1243dSDimitry Andric   const unsigned int DiagList[] = {diag::warn_cast_function_type_strict,
1107bdd1243dSDimitry Andric                                    diag::warn_cast_function_type};
1108bdd1243dSDimitry Andric   for (auto ID : DiagList) {
1109bdd1243dSDimitry Andric     if (!Self.Diags.isIgnored(ID, SrcExpr.get()->getExprLoc())) {
1110bdd1243dSDimitry Andric       DiagID = ID;
1111bdd1243dSDimitry Andric       break;
1112bdd1243dSDimitry Andric     }
1113bdd1243dSDimitry Andric   }
1114bdd1243dSDimitry Andric   if (!DiagID)
1115bdd1243dSDimitry Andric     return 0;
1116fe6060f1SDimitry Andric 
1117fe6060f1SDimitry Andric   QualType SrcType = SrcExpr.get()->getType();
1118fe6060f1SDimitry Andric   const FunctionType *SrcFTy = nullptr;
1119fe6060f1SDimitry Andric   const FunctionType *DstFTy = nullptr;
1120fe6060f1SDimitry Andric   if (((SrcType->isBlockPointerType() || SrcType->isFunctionPointerType()) &&
1121fe6060f1SDimitry Andric        DestType->isFunctionPointerType()) ||
1122fe6060f1SDimitry Andric       (SrcType->isMemberFunctionPointerType() &&
1123fe6060f1SDimitry Andric        DestType->isMemberFunctionPointerType())) {
1124fe6060f1SDimitry Andric     SrcFTy = SrcType->getPointeeType()->castAs<FunctionType>();
1125fe6060f1SDimitry Andric     DstFTy = DestType->getPointeeType()->castAs<FunctionType>();
1126fe6060f1SDimitry Andric   } else if (SrcType->isFunctionType() && DestType->isFunctionReferenceType()) {
1127fe6060f1SDimitry Andric     SrcFTy = SrcType->castAs<FunctionType>();
1128fe6060f1SDimitry Andric     DstFTy = DestType.getNonReferenceType()->castAs<FunctionType>();
1129fe6060f1SDimitry Andric   } else {
1130bdd1243dSDimitry Andric     return 0;
1131fe6060f1SDimitry Andric   }
1132fe6060f1SDimitry Andric   assert(SrcFTy && DstFTy);
1133fe6060f1SDimitry Andric 
1134bdd1243dSDimitry Andric   if (Self.Context.hasSameType(SrcFTy, DstFTy))
1135bdd1243dSDimitry Andric     return 0;
1136bdd1243dSDimitry Andric 
1137bdd1243dSDimitry Andric   // For strict checks, ensure we have an exact match.
1138bdd1243dSDimitry Andric   if (DiagID == diag::warn_cast_function_type_strict)
1139bdd1243dSDimitry Andric     return DiagID;
1140bdd1243dSDimitry Andric 
1141fe6060f1SDimitry Andric   auto IsVoidVoid = [](const FunctionType *T) {
1142fe6060f1SDimitry Andric     if (!T->getReturnType()->isVoidType())
1143fe6060f1SDimitry Andric       return false;
1144fe6060f1SDimitry Andric     if (const auto *PT = T->getAs<FunctionProtoType>())
1145fe6060f1SDimitry Andric       return !PT->isVariadic() && PT->getNumParams() == 0;
1146fe6060f1SDimitry Andric     return false;
1147fe6060f1SDimitry Andric   };
1148fe6060f1SDimitry Andric 
1149fe6060f1SDimitry Andric   // Skip if either function type is void(*)(void)
1150fe6060f1SDimitry Andric   if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy))
1151bdd1243dSDimitry Andric     return 0;
1152fe6060f1SDimitry Andric 
1153fe6060f1SDimitry Andric   // Check return type.
1154fe6060f1SDimitry Andric   if (!argTypeIsABIEquivalent(SrcFTy->getReturnType(), DstFTy->getReturnType(),
1155fe6060f1SDimitry Andric                               Self.Context))
1156bdd1243dSDimitry Andric     return DiagID;
1157fe6060f1SDimitry Andric 
1158fe6060f1SDimitry Andric   // Check if either has unspecified number of parameters
1159fe6060f1SDimitry Andric   if (SrcFTy->isFunctionNoProtoType() || DstFTy->isFunctionNoProtoType())
1160bdd1243dSDimitry Andric     return 0;
1161fe6060f1SDimitry Andric 
1162fe6060f1SDimitry Andric   // Check parameter types.
1163fe6060f1SDimitry Andric 
1164fe6060f1SDimitry Andric   const auto *SrcFPTy = cast<FunctionProtoType>(SrcFTy);
1165fe6060f1SDimitry Andric   const auto *DstFPTy = cast<FunctionProtoType>(DstFTy);
1166fe6060f1SDimitry Andric 
1167fe6060f1SDimitry Andric   // In a cast involving function types with a variable argument list only the
1168fe6060f1SDimitry Andric   // types of initial arguments that are provided are considered.
1169fe6060f1SDimitry Andric   unsigned NumParams = SrcFPTy->getNumParams();
1170fe6060f1SDimitry Andric   unsigned DstNumParams = DstFPTy->getNumParams();
1171fe6060f1SDimitry Andric   if (NumParams > DstNumParams) {
1172fe6060f1SDimitry Andric     if (!DstFPTy->isVariadic())
1173bdd1243dSDimitry Andric       return DiagID;
1174fe6060f1SDimitry Andric     NumParams = DstNumParams;
1175fe6060f1SDimitry Andric   } else if (NumParams < DstNumParams) {
1176fe6060f1SDimitry Andric     if (!SrcFPTy->isVariadic())
1177bdd1243dSDimitry Andric       return DiagID;
1178fe6060f1SDimitry Andric   }
1179fe6060f1SDimitry Andric 
1180fe6060f1SDimitry Andric   for (unsigned i = 0; i < NumParams; ++i)
1181fe6060f1SDimitry Andric     if (!argTypeIsABIEquivalent(SrcFPTy->getParamType(i),
1182fe6060f1SDimitry Andric                                 DstFPTy->getParamType(i), Self.Context))
1183bdd1243dSDimitry Andric       return DiagID;
1184fe6060f1SDimitry Andric 
1185bdd1243dSDimitry Andric   return 0;
1186fe6060f1SDimitry Andric }
1187fe6060f1SDimitry Andric 
11880b57cec5SDimitry Andric /// CheckReinterpretCast - Check that a reinterpret_cast\<DestType\>(SrcExpr) is
11890b57cec5SDimitry Andric /// valid.
11900b57cec5SDimitry Andric /// Refer to C++ 5.2.10 for details. reinterpret_cast is typically used in code
11910b57cec5SDimitry Andric /// like this:
11920b57cec5SDimitry Andric /// char *bytes = reinterpret_cast\<char*\>(int_ptr);
11930b57cec5SDimitry Andric void CastOperation::CheckReinterpretCast() {
1194fe6060f1SDimitry Andric   if (ValueKind == VK_PRValue && !isPlaceholder(BuiltinType::Overload))
11950b57cec5SDimitry Andric     SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
11960b57cec5SDimitry Andric   else
11970b57cec5SDimitry Andric     checkNonOverloadPlaceholders();
11980b57cec5SDimitry Andric   if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
11990b57cec5SDimitry Andric     return;
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric   unsigned msg = diag::err_bad_cxx_cast_generic;
12020b57cec5SDimitry Andric   TryCastResult tcr =
12030b57cec5SDimitry Andric     TryReinterpretCast(Self, SrcExpr, DestType,
12040b57cec5SDimitry Andric                        /*CStyle*/false, OpRange, msg, Kind);
12050b57cec5SDimitry Andric   if (tcr != TC_Success && msg != 0) {
12060b57cec5SDimitry Andric     if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
12070b57cec5SDimitry Andric       return;
12080b57cec5SDimitry Andric     if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
12090b57cec5SDimitry Andric       //FIXME: &f<int>; is overloaded and resolvable
12100b57cec5SDimitry Andric       Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload)
12110b57cec5SDimitry Andric         << OverloadExpr::find(SrcExpr.get()).Expression->getName()
12120b57cec5SDimitry Andric         << DestType << OpRange;
12130b57cec5SDimitry Andric       Self.NoteAllOverloadCandidates(SrcExpr.get());
12140b57cec5SDimitry Andric 
12150b57cec5SDimitry Andric     } else {
12160b57cec5SDimitry Andric       diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(),
12170b57cec5SDimitry Andric                       DestType, /*listInitialization=*/false);
12180b57cec5SDimitry Andric     }
12190b57cec5SDimitry Andric   }
12200b57cec5SDimitry Andric 
12210b57cec5SDimitry Andric   if (isValidCast(tcr)) {
12220b57cec5SDimitry Andric     if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1223*0fca6ea1SDimitry Andric       checkObjCConversion(CheckedConversionKind::OtherCast);
12240b57cec5SDimitry Andric     DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange);
1225fe6060f1SDimitry Andric 
1226bdd1243dSDimitry Andric     if (unsigned DiagID = checkCastFunctionType(Self, SrcExpr, DestType))
1227bdd1243dSDimitry Andric       Self.Diag(OpRange.getBegin(), DiagID)
1228fe6060f1SDimitry Andric           << SrcExpr.get()->getType() << DestType << OpRange;
12290b57cec5SDimitry Andric   } else {
12300b57cec5SDimitry Andric     SrcExpr = ExprError();
12310b57cec5SDimitry Andric   }
12320b57cec5SDimitry Andric }
12330b57cec5SDimitry Andric 
12340b57cec5SDimitry Andric 
12350b57cec5SDimitry Andric /// CheckStaticCast - Check that a static_cast\<DestType\>(SrcExpr) is valid.
12360b57cec5SDimitry Andric /// Refer to C++ 5.2.9 for details. Static casts are mostly used for making
12370b57cec5SDimitry Andric /// implicit conversions explicit and getting rid of data loss warnings.
12380b57cec5SDimitry Andric void CastOperation::CheckStaticCast() {
12395ffd83dbSDimitry Andric   CheckNoDerefRAII NoderefCheck(*this);
12405ffd83dbSDimitry Andric 
12410b57cec5SDimitry Andric   if (isPlaceholder()) {
12420b57cec5SDimitry Andric     checkNonOverloadPlaceholders();
12430b57cec5SDimitry Andric     if (SrcExpr.isInvalid())
12440b57cec5SDimitry Andric       return;
12450b57cec5SDimitry Andric   }
12460b57cec5SDimitry Andric 
12470b57cec5SDimitry Andric   // This test is outside everything else because it's the only case where
12480b57cec5SDimitry Andric   // a non-lvalue-reference target type does not lead to decay.
12490b57cec5SDimitry Andric   // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
12500b57cec5SDimitry Andric   if (DestType->isVoidType()) {
12510b57cec5SDimitry Andric     Kind = CK_ToVoid;
12520b57cec5SDimitry Andric 
12530b57cec5SDimitry Andric     if (claimPlaceholder(BuiltinType::Overload)) {
12540b57cec5SDimitry Andric       Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
12550b57cec5SDimitry Andric                 false, // Decay Function to ptr
12560b57cec5SDimitry Andric                 true, // Complain
12570b57cec5SDimitry Andric                 OpRange, DestType, diag::err_bad_static_cast_overload);
12580b57cec5SDimitry Andric       if (SrcExpr.isInvalid())
12590b57cec5SDimitry Andric         return;
12600b57cec5SDimitry Andric     }
12610b57cec5SDimitry Andric 
12620b57cec5SDimitry Andric     SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
12630b57cec5SDimitry Andric     return;
12640b57cec5SDimitry Andric   }
12650b57cec5SDimitry Andric 
1266fe6060f1SDimitry Andric   if (ValueKind == VK_PRValue && !DestType->isRecordType() &&
12670b57cec5SDimitry Andric       !isPlaceholder(BuiltinType::Overload)) {
12680b57cec5SDimitry Andric     SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
12690b57cec5SDimitry Andric     if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
12700b57cec5SDimitry Andric       return;
12710b57cec5SDimitry Andric   }
12720b57cec5SDimitry Andric 
12730b57cec5SDimitry Andric   unsigned msg = diag::err_bad_cxx_cast_generic;
1274*0fca6ea1SDimitry Andric   TryCastResult tcr =
1275*0fca6ea1SDimitry Andric       TryStaticCast(Self, SrcExpr, DestType, CheckedConversionKind::OtherCast,
1276*0fca6ea1SDimitry Andric                     OpRange, msg, Kind, BasePath, /*ListInitialization=*/false);
12770b57cec5SDimitry Andric   if (tcr != TC_Success && msg != 0) {
12780b57cec5SDimitry Andric     if (SrcExpr.isInvalid())
12790b57cec5SDimitry Andric       return;
12800b57cec5SDimitry Andric     if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
12810b57cec5SDimitry Andric       OverloadExpr* oe = OverloadExpr::find(SrcExpr.get()).Expression;
12820b57cec5SDimitry Andric       Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)
12830b57cec5SDimitry Andric         << oe->getName() << DestType << OpRange
12840b57cec5SDimitry Andric         << oe->getQualifierLoc().getSourceRange();
12850b57cec5SDimitry Andric       Self.NoteAllOverloadCandidates(SrcExpr.get());
12860b57cec5SDimitry Andric     } else {
12870b57cec5SDimitry Andric       diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr.get(), DestType,
12880b57cec5SDimitry Andric                       /*listInitialization=*/false);
12890b57cec5SDimitry Andric     }
12900b57cec5SDimitry Andric   }
12910b57cec5SDimitry Andric 
12920b57cec5SDimitry Andric   if (isValidCast(tcr)) {
12930b57cec5SDimitry Andric     if (Kind == CK_BitCast)
12940b57cec5SDimitry Andric       checkCastAlign();
12950b57cec5SDimitry Andric     if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
1296*0fca6ea1SDimitry Andric       checkObjCConversion(CheckedConversionKind::OtherCast);
12970b57cec5SDimitry Andric   } else {
12980b57cec5SDimitry Andric     SrcExpr = ExprError();
12990b57cec5SDimitry Andric   }
13000b57cec5SDimitry Andric }
13010b57cec5SDimitry Andric 
13020b57cec5SDimitry Andric static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType) {
13030b57cec5SDimitry Andric   auto *SrcPtrType = SrcType->getAs<PointerType>();
13040b57cec5SDimitry Andric   if (!SrcPtrType)
13050b57cec5SDimitry Andric     return false;
13060b57cec5SDimitry Andric   auto *DestPtrType = DestType->getAs<PointerType>();
13070b57cec5SDimitry Andric   if (!DestPtrType)
13080b57cec5SDimitry Andric     return false;
13090b57cec5SDimitry Andric   return SrcPtrType->getPointeeType().getAddressSpace() !=
13100b57cec5SDimitry Andric          DestPtrType->getPointeeType().getAddressSpace();
13110b57cec5SDimitry Andric }
13120b57cec5SDimitry Andric 
13130b57cec5SDimitry Andric /// TryStaticCast - Check if a static cast can be performed, and do so if
13140b57cec5SDimitry Andric /// possible. If @p CStyle, ignore access restrictions on hierarchy casting
13150b57cec5SDimitry Andric /// and casting away constness.
13160b57cec5SDimitry Andric static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
1317*0fca6ea1SDimitry Andric                                    QualType DestType, CheckedConversionKind CCK,
13180b57cec5SDimitry Andric                                    SourceRange OpRange, unsigned &msg,
13190b57cec5SDimitry Andric                                    CastKind &Kind, CXXCastPath &BasePath,
13200b57cec5SDimitry Andric                                    bool ListInitialization) {
13210b57cec5SDimitry Andric   // Determine whether we have the semantics of a C-style cast.
1322*0fca6ea1SDimitry Andric   bool CStyle = (CCK == CheckedConversionKind::CStyleCast ||
1323*0fca6ea1SDimitry Andric                  CCK == CheckedConversionKind::FunctionalCast);
13240b57cec5SDimitry Andric 
13250b57cec5SDimitry Andric   // The order the tests is not entirely arbitrary. There is one conversion
13260b57cec5SDimitry Andric   // that can be handled in two different ways. Given:
13270b57cec5SDimitry Andric   // struct A {};
13280b57cec5SDimitry Andric   // struct B : public A {
13290b57cec5SDimitry Andric   //   B(); B(const A&);
13300b57cec5SDimitry Andric   // };
13310b57cec5SDimitry Andric   // const A &a = B();
13320b57cec5SDimitry Andric   // the cast static_cast<const B&>(a) could be seen as either a static
13330b57cec5SDimitry Andric   // reference downcast, or an explicit invocation of the user-defined
13340b57cec5SDimitry Andric   // conversion using B's conversion constructor.
13350b57cec5SDimitry Andric   // DR 427 specifies that the downcast is to be applied here.
13360b57cec5SDimitry Andric 
13370b57cec5SDimitry Andric   // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
13380b57cec5SDimitry Andric   // Done outside this function.
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric   TryCastResult tcr;
13410b57cec5SDimitry Andric 
13420b57cec5SDimitry Andric   // C++ 5.2.9p5, reference downcast.
13430b57cec5SDimitry Andric   // See the function for details.
13440b57cec5SDimitry Andric   // DR 427 specifies that this is to be applied before paragraph 2.
13450b57cec5SDimitry Andric   tcr = TryStaticReferenceDowncast(Self, SrcExpr.get(), DestType, CStyle,
13460b57cec5SDimitry Andric                                    OpRange, msg, Kind, BasePath);
13470b57cec5SDimitry Andric   if (tcr != TC_NotApplicable)
13480b57cec5SDimitry Andric     return tcr;
13490b57cec5SDimitry Andric 
13500b57cec5SDimitry Andric   // C++11 [expr.static.cast]p3:
13510b57cec5SDimitry Andric   //   A glvalue of type "cv1 T1" can be cast to type "rvalue reference to cv2
13520b57cec5SDimitry Andric   //   T2" if "cv2 T2" is reference-compatible with "cv1 T1".
13530b57cec5SDimitry Andric   tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, Kind,
13540b57cec5SDimitry Andric                               BasePath, msg);
13550b57cec5SDimitry Andric   if (tcr != TC_NotApplicable)
13560b57cec5SDimitry Andric     return tcr;
13570b57cec5SDimitry Andric 
13580b57cec5SDimitry Andric   // C++ 5.2.9p2: An expression e can be explicitly converted to a type T
13590b57cec5SDimitry Andric   //   [...] if the declaration "T t(e);" is well-formed, [...].
13600b57cec5SDimitry Andric   tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CCK, OpRange, msg,
13610b57cec5SDimitry Andric                               Kind, ListInitialization);
13620b57cec5SDimitry Andric   if (SrcExpr.isInvalid())
13630b57cec5SDimitry Andric     return TC_Failed;
13640b57cec5SDimitry Andric   if (tcr != TC_NotApplicable)
13650b57cec5SDimitry Andric     return tcr;
13660b57cec5SDimitry Andric 
13670b57cec5SDimitry Andric   // C++ 5.2.9p6: May apply the reverse of any standard conversion, except
13680b57cec5SDimitry Andric   // lvalue-to-rvalue, array-to-pointer, function-to-pointer, and boolean
13690b57cec5SDimitry Andric   // conversions, subject to further restrictions.
13700b57cec5SDimitry Andric   // Also, C++ 5.2.9p1 forbids casting away constness, which makes reversal
1371349cc55cSDimitry Andric   // of qualification conversions impossible. (In C++20, adding an array bound
1372349cc55cSDimitry Andric   // would be the reverse of a qualification conversion, but adding permission
1373349cc55cSDimitry Andric   // to add an array bound in a static_cast is a wording oversight.)
13740b57cec5SDimitry Andric   // In the CStyle case, the earlier attempt to const_cast should have taken
13750b57cec5SDimitry Andric   // care of reverse qualification conversions.
13760b57cec5SDimitry Andric 
13770b57cec5SDimitry Andric   QualType SrcType = Self.Context.getCanonicalType(SrcExpr.get()->getType());
13780b57cec5SDimitry Andric 
13790b57cec5SDimitry Andric   // C++0x 5.2.9p9: A value of a scoped enumeration type can be explicitly
13800b57cec5SDimitry Andric   // converted to an integral type. [...] A value of a scoped enumeration type
13810b57cec5SDimitry Andric   // can also be explicitly converted to a floating-point type [...].
13820b57cec5SDimitry Andric   if (const EnumType *Enum = SrcType->getAs<EnumType>()) {
13830b57cec5SDimitry Andric     if (Enum->getDecl()->isScoped()) {
13840b57cec5SDimitry Andric       if (DestType->isBooleanType()) {
13850b57cec5SDimitry Andric         Kind = CK_IntegralToBoolean;
13860b57cec5SDimitry Andric         return TC_Success;
13870b57cec5SDimitry Andric       } else if (DestType->isIntegralType(Self.Context)) {
13880b57cec5SDimitry Andric         Kind = CK_IntegralCast;
13890b57cec5SDimitry Andric         return TC_Success;
13900b57cec5SDimitry Andric       } else if (DestType->isRealFloatingType()) {
13910b57cec5SDimitry Andric         Kind = CK_IntegralToFloating;
13920b57cec5SDimitry Andric         return TC_Success;
13930b57cec5SDimitry Andric       }
13940b57cec5SDimitry Andric     }
13950b57cec5SDimitry Andric   }
13960b57cec5SDimitry Andric 
13970b57cec5SDimitry Andric   // Reverse integral promotion/conversion. All such conversions are themselves
13980b57cec5SDimitry Andric   // again integral promotions or conversions and are thus already handled by
13990b57cec5SDimitry Andric   // p2 (TryDirectInitialization above).
14000b57cec5SDimitry Andric   // (Note: any data loss warnings should be suppressed.)
14010b57cec5SDimitry Andric   // The exception is the reverse of enum->integer, i.e. integer->enum (and
14020b57cec5SDimitry Andric   // enum->enum). See also C++ 5.2.9p7.
14030b57cec5SDimitry Andric   // The same goes for reverse floating point promotion/conversion and
14040b57cec5SDimitry Andric   // floating-integral conversions. Again, only floating->enum is relevant.
14050b57cec5SDimitry Andric   if (DestType->isEnumeralType()) {
1406480093f4SDimitry Andric     if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
1407480093f4SDimitry Andric                                  diag::err_bad_cast_incomplete)) {
1408480093f4SDimitry Andric       SrcExpr = ExprError();
1409480093f4SDimitry Andric       return TC_Failed;
1410480093f4SDimitry Andric     }
14110b57cec5SDimitry Andric     if (SrcType->isIntegralOrEnumerationType()) {
1412e8d8bef9SDimitry Andric       // [expr.static.cast]p10 If the enumeration type has a fixed underlying
1413e8d8bef9SDimitry Andric       // type, the value is first converted to that type by integral conversion
141481ad6265SDimitry Andric       const EnumType *Enum = DestType->castAs<EnumType>();
1415e8d8bef9SDimitry Andric       Kind = Enum->getDecl()->isFixed() &&
1416e8d8bef9SDimitry Andric                      Enum->getDecl()->getIntegerType()->isBooleanType()
1417e8d8bef9SDimitry Andric                  ? CK_IntegralToBoolean
1418e8d8bef9SDimitry Andric                  : CK_IntegralCast;
14190b57cec5SDimitry Andric       return TC_Success;
14200b57cec5SDimitry Andric     } else if (SrcType->isRealFloatingType())   {
14210b57cec5SDimitry Andric       Kind = CK_FloatingToIntegral;
14220b57cec5SDimitry Andric       return TC_Success;
14230b57cec5SDimitry Andric     }
14240b57cec5SDimitry Andric   }
14250b57cec5SDimitry Andric 
14260b57cec5SDimitry Andric   // Reverse pointer upcast. C++ 4.10p3 specifies pointer upcast.
14270b57cec5SDimitry Andric   // C++ 5.2.9p8 additionally disallows a cast path through virtual inheritance.
14280b57cec5SDimitry Andric   tcr = TryStaticPointerDowncast(Self, SrcType, DestType, CStyle, OpRange, msg,
14290b57cec5SDimitry Andric                                  Kind, BasePath);
14300b57cec5SDimitry Andric   if (tcr != TC_NotApplicable)
14310b57cec5SDimitry Andric     return tcr;
14320b57cec5SDimitry Andric 
14330b57cec5SDimitry Andric   // Reverse member pointer conversion. C++ 4.11 specifies member pointer
14340b57cec5SDimitry Andric   // conversion. C++ 5.2.9p9 has additional information.
14350b57cec5SDimitry Andric   // DR54's access restrictions apply here also.
14360b57cec5SDimitry Andric   tcr = TryStaticMemberPointerUpcast(Self, SrcExpr, SrcType, DestType, CStyle,
14370b57cec5SDimitry Andric                                      OpRange, msg, Kind, BasePath);
14380b57cec5SDimitry Andric   if (tcr != TC_NotApplicable)
14390b57cec5SDimitry Andric     return tcr;
14400b57cec5SDimitry Andric 
14410b57cec5SDimitry Andric   // Reverse pointer conversion to void*. C++ 4.10.p2 specifies conversion to
14420b57cec5SDimitry Andric   // void*. C++ 5.2.9p10 specifies additional restrictions, which really is
14430b57cec5SDimitry Andric   // just the usual constness stuff.
14440b57cec5SDimitry Andric   if (const PointerType *SrcPointer = SrcType->getAs<PointerType>()) {
14450b57cec5SDimitry Andric     QualType SrcPointee = SrcPointer->getPointeeType();
14460b57cec5SDimitry Andric     if (SrcPointee->isVoidType()) {
14470b57cec5SDimitry Andric       if (const PointerType *DestPointer = DestType->getAs<PointerType>()) {
14480b57cec5SDimitry Andric         QualType DestPointee = DestPointer->getPointeeType();
14490b57cec5SDimitry Andric         if (DestPointee->isIncompleteOrObjectType()) {
14500b57cec5SDimitry Andric           // This is definitely the intended conversion, but it might fail due
14510b57cec5SDimitry Andric           // to a qualifier violation. Note that we permit Objective-C lifetime
14520b57cec5SDimitry Andric           // and GC qualifier mismatches here.
14530b57cec5SDimitry Andric           if (!CStyle) {
14540b57cec5SDimitry Andric             Qualifiers DestPointeeQuals = DestPointee.getQualifiers();
14550b57cec5SDimitry Andric             Qualifiers SrcPointeeQuals = SrcPointee.getQualifiers();
14560b57cec5SDimitry Andric             DestPointeeQuals.removeObjCGCAttr();
14570b57cec5SDimitry Andric             DestPointeeQuals.removeObjCLifetime();
14580b57cec5SDimitry Andric             SrcPointeeQuals.removeObjCGCAttr();
14590b57cec5SDimitry Andric             SrcPointeeQuals.removeObjCLifetime();
14600b57cec5SDimitry Andric             if (DestPointeeQuals != SrcPointeeQuals &&
14610b57cec5SDimitry Andric                 !DestPointeeQuals.compatiblyIncludes(SrcPointeeQuals)) {
14620b57cec5SDimitry Andric               msg = diag::err_bad_cxx_cast_qualifiers_away;
14630b57cec5SDimitry Andric               return TC_Failed;
14640b57cec5SDimitry Andric             }
14650b57cec5SDimitry Andric           }
14660b57cec5SDimitry Andric           Kind = IsAddressSpaceConversion(SrcType, DestType)
14670b57cec5SDimitry Andric                      ? CK_AddressSpaceConversion
14680b57cec5SDimitry Andric                      : CK_BitCast;
14690b57cec5SDimitry Andric           return TC_Success;
14700b57cec5SDimitry Andric         }
14710b57cec5SDimitry Andric 
14720b57cec5SDimitry Andric         // Microsoft permits static_cast from 'pointer-to-void' to
14730b57cec5SDimitry Andric         // 'pointer-to-function'.
14740b57cec5SDimitry Andric         if (!CStyle && Self.getLangOpts().MSVCCompat &&
14750b57cec5SDimitry Andric             DestPointee->isFunctionType()) {
14760b57cec5SDimitry Andric           Self.Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange;
14770b57cec5SDimitry Andric           Kind = CK_BitCast;
14780b57cec5SDimitry Andric           return TC_Success;
14790b57cec5SDimitry Andric         }
14800b57cec5SDimitry Andric       }
14810b57cec5SDimitry Andric       else if (DestType->isObjCObjectPointerType()) {
14820b57cec5SDimitry Andric         // allow both c-style cast and static_cast of objective-c pointers as
14830b57cec5SDimitry Andric         // they are pervasive.
14840b57cec5SDimitry Andric         Kind = CK_CPointerToObjCPointerCast;
14850b57cec5SDimitry Andric         return TC_Success;
14860b57cec5SDimitry Andric       }
14870b57cec5SDimitry Andric       else if (CStyle && DestType->isBlockPointerType()) {
14880b57cec5SDimitry Andric         // allow c-style cast of void * to block pointers.
14890b57cec5SDimitry Andric         Kind = CK_AnyPointerToBlockPointerCast;
14900b57cec5SDimitry Andric         return TC_Success;
14910b57cec5SDimitry Andric       }
14920b57cec5SDimitry Andric     }
14930b57cec5SDimitry Andric   }
14940b57cec5SDimitry Andric   // Allow arbitrary objective-c pointer conversion with static casts.
14950b57cec5SDimitry Andric   if (SrcType->isObjCObjectPointerType() &&
14960b57cec5SDimitry Andric       DestType->isObjCObjectPointerType()) {
14970b57cec5SDimitry Andric     Kind = CK_BitCast;
14980b57cec5SDimitry Andric     return TC_Success;
14990b57cec5SDimitry Andric   }
15000b57cec5SDimitry Andric   // Allow ns-pointer to cf-pointer conversion in either direction
15010b57cec5SDimitry Andric   // with static casts.
15020b57cec5SDimitry Andric   if (!CStyle &&
1503*0fca6ea1SDimitry Andric       Self.ObjC().CheckTollFreeBridgeStaticCast(DestType, SrcExpr.get(), Kind))
15040b57cec5SDimitry Andric     return TC_Success;
15050b57cec5SDimitry Andric 
15060b57cec5SDimitry Andric   // See if it looks like the user is trying to convert between
15070b57cec5SDimitry Andric   // related record types, and select a better diagnostic if so.
15080b57cec5SDimitry Andric   if (auto SrcPointer = SrcType->getAs<PointerType>())
15090b57cec5SDimitry Andric     if (auto DestPointer = DestType->getAs<PointerType>())
15100b57cec5SDimitry Andric       if (SrcPointer->getPointeeType()->getAs<RecordType>() &&
15110b57cec5SDimitry Andric           DestPointer->getPointeeType()->getAs<RecordType>())
15120b57cec5SDimitry Andric        msg = diag::err_bad_cxx_cast_unrelated_class;
15130b57cec5SDimitry Andric 
1514fe6060f1SDimitry Andric   if (SrcType->isMatrixType() && DestType->isMatrixType()) {
1515fe6060f1SDimitry Andric     if (Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind)) {
1516fe6060f1SDimitry Andric       SrcExpr = ExprError();
1517fe6060f1SDimitry Andric       return TC_Failed;
1518fe6060f1SDimitry Andric     }
1519fe6060f1SDimitry Andric     return TC_Success;
1520fe6060f1SDimitry Andric   }
1521fe6060f1SDimitry Andric 
15220b57cec5SDimitry Andric   // We tried everything. Everything! Nothing works! :-(
15230b57cec5SDimitry Andric   return TC_NotApplicable;
15240b57cec5SDimitry Andric }
15250b57cec5SDimitry Andric 
15260b57cec5SDimitry Andric /// Tests whether a conversion according to N2844 is valid.
15270b57cec5SDimitry Andric TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr,
15280b57cec5SDimitry Andric                                     QualType DestType, bool CStyle,
15290b57cec5SDimitry Andric                                     CastKind &Kind, CXXCastPath &BasePath,
15300b57cec5SDimitry Andric                                     unsigned &msg) {
15310b57cec5SDimitry Andric   // C++11 [expr.static.cast]p3:
15320b57cec5SDimitry Andric   //   A glvalue of type "cv1 T1" can be cast to type "rvalue reference to
15330b57cec5SDimitry Andric   //   cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".
15340b57cec5SDimitry Andric   const RValueReferenceType *R = DestType->getAs<RValueReferenceType>();
15350b57cec5SDimitry Andric   if (!R)
15360b57cec5SDimitry Andric     return TC_NotApplicable;
15370b57cec5SDimitry Andric 
15380b57cec5SDimitry Andric   if (!SrcExpr->isGLValue())
15390b57cec5SDimitry Andric     return TC_NotApplicable;
15400b57cec5SDimitry Andric 
15410b57cec5SDimitry Andric   // Because we try the reference downcast before this function, from now on
15420b57cec5SDimitry Andric   // this is the only cast possibility, so we issue an error if we fail now.
15430b57cec5SDimitry Andric   // FIXME: Should allow casting away constness if CStyle.
15440b57cec5SDimitry Andric   QualType FromType = SrcExpr->getType();
15450b57cec5SDimitry Andric   QualType ToType = R->getPointeeType();
15460b57cec5SDimitry Andric   if (CStyle) {
15470b57cec5SDimitry Andric     FromType = FromType.getUnqualifiedType();
15480b57cec5SDimitry Andric     ToType = ToType.getUnqualifiedType();
15490b57cec5SDimitry Andric   }
15500b57cec5SDimitry Andric 
1551480093f4SDimitry Andric   Sema::ReferenceConversions RefConv;
15520b57cec5SDimitry Andric   Sema::ReferenceCompareResult RefResult = Self.CompareReferenceRelationship(
1553480093f4SDimitry Andric       SrcExpr->getBeginLoc(), ToType, FromType, &RefConv);
15540b57cec5SDimitry Andric   if (RefResult != Sema::Ref_Compatible) {
15550b57cec5SDimitry Andric     if (CStyle || RefResult == Sema::Ref_Incompatible)
15560b57cec5SDimitry Andric       return TC_NotApplicable;
15570b57cec5SDimitry Andric     // Diagnose types which are reference-related but not compatible here since
15580b57cec5SDimitry Andric     // we can provide better diagnostics. In these cases forwarding to
15590b57cec5SDimitry Andric     // [expr.static.cast]p4 should never result in a well-formed cast.
15600b57cec5SDimitry Andric     msg = SrcExpr->isLValue() ? diag::err_bad_lvalue_to_rvalue_cast
15610b57cec5SDimitry Andric                               : diag::err_bad_rvalue_to_rvalue_cast;
15620b57cec5SDimitry Andric     return TC_Failed;
15630b57cec5SDimitry Andric   }
15640b57cec5SDimitry Andric 
1565480093f4SDimitry Andric   if (RefConv & Sema::ReferenceConversions::DerivedToBase) {
15660b57cec5SDimitry Andric     Kind = CK_DerivedToBase;
15670b57cec5SDimitry Andric     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
15680b57cec5SDimitry Andric                        /*DetectVirtual=*/true);
15690b57cec5SDimitry Andric     if (!Self.IsDerivedFrom(SrcExpr->getBeginLoc(), SrcExpr->getType(),
15700b57cec5SDimitry Andric                             R->getPointeeType(), Paths))
15710b57cec5SDimitry Andric       return TC_NotApplicable;
15720b57cec5SDimitry Andric 
15730b57cec5SDimitry Andric     Self.BuildBasePathArray(Paths, BasePath);
15740b57cec5SDimitry Andric   } else
15750b57cec5SDimitry Andric     Kind = CK_NoOp;
15760b57cec5SDimitry Andric 
15770b57cec5SDimitry Andric   return TC_Success;
15780b57cec5SDimitry Andric }
15790b57cec5SDimitry Andric 
15800b57cec5SDimitry Andric /// Tests whether a conversion according to C++ 5.2.9p5 is valid.
15810b57cec5SDimitry Andric TryCastResult
15820b57cec5SDimitry Andric TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
15830b57cec5SDimitry Andric                            bool CStyle, SourceRange OpRange,
15840b57cec5SDimitry Andric                            unsigned &msg, CastKind &Kind,
15850b57cec5SDimitry Andric                            CXXCastPath &BasePath) {
15860b57cec5SDimitry Andric   // C++ 5.2.9p5: An lvalue of type "cv1 B", where B is a class type, can be
15870b57cec5SDimitry Andric   //   cast to type "reference to cv2 D", where D is a class derived from B,
15880b57cec5SDimitry Andric   //   if a valid standard conversion from "pointer to D" to "pointer to B"
15890b57cec5SDimitry Andric   //   exists, cv2 >= cv1, and B is not a virtual base class of D.
15900b57cec5SDimitry Andric   // In addition, DR54 clarifies that the base must be accessible in the
15910b57cec5SDimitry Andric   // current context. Although the wording of DR54 only applies to the pointer
15920b57cec5SDimitry Andric   // variant of this rule, the intent is clearly for it to apply to the this
15930b57cec5SDimitry Andric   // conversion as well.
15940b57cec5SDimitry Andric 
15950b57cec5SDimitry Andric   const ReferenceType *DestReference = DestType->getAs<ReferenceType>();
15960b57cec5SDimitry Andric   if (!DestReference) {
15970b57cec5SDimitry Andric     return TC_NotApplicable;
15980b57cec5SDimitry Andric   }
15990b57cec5SDimitry Andric   bool RValueRef = DestReference->isRValueReferenceType();
16000b57cec5SDimitry Andric   if (!RValueRef && !SrcExpr->isLValue()) {
16010b57cec5SDimitry Andric     // We know the left side is an lvalue reference, so we can suggest a reason.
16020b57cec5SDimitry Andric     msg = diag::err_bad_cxx_cast_rvalue;
16030b57cec5SDimitry Andric     return TC_NotApplicable;
16040b57cec5SDimitry Andric   }
16050b57cec5SDimitry Andric 
16060b57cec5SDimitry Andric   QualType DestPointee = DestReference->getPointeeType();
16070b57cec5SDimitry Andric 
16080b57cec5SDimitry Andric   // FIXME: If the source is a prvalue, we should issue a warning (because the
16090b57cec5SDimitry Andric   // cast always has undefined behavior), and for AST consistency, we should
16100b57cec5SDimitry Andric   // materialize a temporary.
16110b57cec5SDimitry Andric   return TryStaticDowncast(Self,
16120b57cec5SDimitry Andric                            Self.Context.getCanonicalType(SrcExpr->getType()),
16130b57cec5SDimitry Andric                            Self.Context.getCanonicalType(DestPointee), CStyle,
16140b57cec5SDimitry Andric                            OpRange, SrcExpr->getType(), DestType, msg, Kind,
16150b57cec5SDimitry Andric                            BasePath);
16160b57cec5SDimitry Andric }
16170b57cec5SDimitry Andric 
16180b57cec5SDimitry Andric /// Tests whether a conversion according to C++ 5.2.9p8 is valid.
16190b57cec5SDimitry Andric TryCastResult
16200b57cec5SDimitry Andric TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType,
16210b57cec5SDimitry Andric                          bool CStyle, SourceRange OpRange,
16220b57cec5SDimitry Andric                          unsigned &msg, CastKind &Kind,
16230b57cec5SDimitry Andric                          CXXCastPath &BasePath) {
16240b57cec5SDimitry Andric   // C++ 5.2.9p8: An rvalue of type "pointer to cv1 B", where B is a class
16250b57cec5SDimitry Andric   //   type, can be converted to an rvalue of type "pointer to cv2 D", where D
16260b57cec5SDimitry Andric   //   is a class derived from B, if a valid standard conversion from "pointer
16270b57cec5SDimitry Andric   //   to D" to "pointer to B" exists, cv2 >= cv1, and B is not a virtual base
16280b57cec5SDimitry Andric   //   class of D.
16290b57cec5SDimitry Andric   // In addition, DR54 clarifies that the base must be accessible in the
16300b57cec5SDimitry Andric   // current context.
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric   const PointerType *DestPointer = DestType->getAs<PointerType>();
16330b57cec5SDimitry Andric   if (!DestPointer) {
16340b57cec5SDimitry Andric     return TC_NotApplicable;
16350b57cec5SDimitry Andric   }
16360b57cec5SDimitry Andric 
16370b57cec5SDimitry Andric   const PointerType *SrcPointer = SrcType->getAs<PointerType>();
16380b57cec5SDimitry Andric   if (!SrcPointer) {
16390b57cec5SDimitry Andric     msg = diag::err_bad_static_cast_pointer_nonpointer;
16400b57cec5SDimitry Andric     return TC_NotApplicable;
16410b57cec5SDimitry Andric   }
16420b57cec5SDimitry Andric 
16430b57cec5SDimitry Andric   return TryStaticDowncast(Self,
16440b57cec5SDimitry Andric                    Self.Context.getCanonicalType(SrcPointer->getPointeeType()),
16450b57cec5SDimitry Andric                   Self.Context.getCanonicalType(DestPointer->getPointeeType()),
16460b57cec5SDimitry Andric                            CStyle, OpRange, SrcType, DestType, msg, Kind,
16470b57cec5SDimitry Andric                            BasePath);
16480b57cec5SDimitry Andric }
16490b57cec5SDimitry Andric 
16500b57cec5SDimitry Andric /// TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and
16510b57cec5SDimitry Andric /// TryStaticPointerDowncast. Tests whether a static downcast from SrcType to
16520b57cec5SDimitry Andric /// DestType is possible and allowed.
16530b57cec5SDimitry Andric TryCastResult
16540b57cec5SDimitry Andric TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
16550b57cec5SDimitry Andric                   bool CStyle, SourceRange OpRange, QualType OrigSrcType,
16560b57cec5SDimitry Andric                   QualType OrigDestType, unsigned &msg,
16570b57cec5SDimitry Andric                   CastKind &Kind, CXXCastPath &BasePath) {
16580b57cec5SDimitry Andric   // We can only work with complete types. But don't complain if it doesn't work
16590b57cec5SDimitry Andric   if (!Self.isCompleteType(OpRange.getBegin(), SrcType) ||
16600b57cec5SDimitry Andric       !Self.isCompleteType(OpRange.getBegin(), DestType))
16610b57cec5SDimitry Andric     return TC_NotApplicable;
16620b57cec5SDimitry Andric 
16630b57cec5SDimitry Andric   // Downcast can only happen in class hierarchies, so we need classes.
16640b57cec5SDimitry Andric   if (!DestType->getAs<RecordType>() || !SrcType->getAs<RecordType>()) {
16650b57cec5SDimitry Andric     return TC_NotApplicable;
16660b57cec5SDimitry Andric   }
16670b57cec5SDimitry Andric 
16680b57cec5SDimitry Andric   CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
16690b57cec5SDimitry Andric                      /*DetectVirtual=*/true);
16700b57cec5SDimitry Andric   if (!Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths)) {
16710b57cec5SDimitry Andric     return TC_NotApplicable;
16720b57cec5SDimitry Andric   }
16730b57cec5SDimitry Andric 
16740b57cec5SDimitry Andric   // Target type does derive from source type. Now we're serious. If an error
16750b57cec5SDimitry Andric   // appears now, it's not ignored.
16760b57cec5SDimitry Andric   // This may not be entirely in line with the standard. Take for example:
16770b57cec5SDimitry Andric   // struct A {};
16780b57cec5SDimitry Andric   // struct B : virtual A {
16790b57cec5SDimitry Andric   //   B(A&);
16800b57cec5SDimitry Andric   // };
16810b57cec5SDimitry Andric   //
16820b57cec5SDimitry Andric   // void f()
16830b57cec5SDimitry Andric   // {
16840b57cec5SDimitry Andric   //   (void)static_cast<const B&>(*((A*)0));
16850b57cec5SDimitry Andric   // }
16860b57cec5SDimitry Andric   // As far as the standard is concerned, p5 does not apply (A is virtual), so
16870b57cec5SDimitry Andric   // p2 should be used instead - "const B& t(*((A*)0));" is perfectly valid.
16880b57cec5SDimitry Andric   // However, both GCC and Comeau reject this example, and accepting it would
16890b57cec5SDimitry Andric   // mean more complex code if we're to preserve the nice error message.
16900b57cec5SDimitry Andric   // FIXME: Being 100% compliant here would be nice to have.
16910b57cec5SDimitry Andric 
16920b57cec5SDimitry Andric   // Must preserve cv, as always, unless we're in C-style mode.
16930b57cec5SDimitry Andric   if (!CStyle && !DestType.isAtLeastAsQualifiedAs(SrcType)) {
16940b57cec5SDimitry Andric     msg = diag::err_bad_cxx_cast_qualifiers_away;
16950b57cec5SDimitry Andric     return TC_Failed;
16960b57cec5SDimitry Andric   }
16970b57cec5SDimitry Andric 
16980b57cec5SDimitry Andric   if (Paths.isAmbiguous(SrcType.getUnqualifiedType())) {
16990b57cec5SDimitry Andric     // This code is analoguous to that in CheckDerivedToBaseConversion, except
17000b57cec5SDimitry Andric     // that it builds the paths in reverse order.
17010b57cec5SDimitry Andric     // To sum up: record all paths to the base and build a nice string from
17020b57cec5SDimitry Andric     // them. Use it to spice up the error message.
17030b57cec5SDimitry Andric     if (!Paths.isRecordingPaths()) {
17040b57cec5SDimitry Andric       Paths.clear();
17050b57cec5SDimitry Andric       Paths.setRecordingPaths(true);
17060b57cec5SDimitry Andric       Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths);
17070b57cec5SDimitry Andric     }
17080b57cec5SDimitry Andric     std::string PathDisplayStr;
17090b57cec5SDimitry Andric     std::set<unsigned> DisplayedPaths;
17100b57cec5SDimitry Andric     for (clang::CXXBasePath &Path : Paths) {
17110b57cec5SDimitry Andric       if (DisplayedPaths.insert(Path.back().SubobjectNumber).second) {
17120b57cec5SDimitry Andric         // We haven't displayed a path to this particular base
17130b57cec5SDimitry Andric         // class subobject yet.
17140b57cec5SDimitry Andric         PathDisplayStr += "\n    ";
17150b57cec5SDimitry Andric         for (CXXBasePathElement &PE : llvm::reverse(Path))
17160b57cec5SDimitry Andric           PathDisplayStr += PE.Base->getType().getAsString() + " -> ";
17170b57cec5SDimitry Andric         PathDisplayStr += QualType(DestType).getAsString();
17180b57cec5SDimitry Andric       }
17190b57cec5SDimitry Andric     }
17200b57cec5SDimitry Andric 
17210b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_ambiguous_base_to_derived_cast)
17220b57cec5SDimitry Andric       << QualType(SrcType).getUnqualifiedType()
17230b57cec5SDimitry Andric       << QualType(DestType).getUnqualifiedType()
17240b57cec5SDimitry Andric       << PathDisplayStr << OpRange;
17250b57cec5SDimitry Andric     msg = 0;
17260b57cec5SDimitry Andric     return TC_Failed;
17270b57cec5SDimitry Andric   }
17280b57cec5SDimitry Andric 
17290b57cec5SDimitry Andric   if (Paths.getDetectedVirtual() != nullptr) {
17300b57cec5SDimitry Andric     QualType VirtualBase(Paths.getDetectedVirtual(), 0);
17310b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_static_downcast_via_virtual)
17320b57cec5SDimitry Andric       << OrigSrcType << OrigDestType << VirtualBase << OpRange;
17330b57cec5SDimitry Andric     msg = 0;
17340b57cec5SDimitry Andric     return TC_Failed;
17350b57cec5SDimitry Andric   }
17360b57cec5SDimitry Andric 
17370b57cec5SDimitry Andric   if (!CStyle) {
17380b57cec5SDimitry Andric     switch (Self.CheckBaseClassAccess(OpRange.getBegin(),
17390b57cec5SDimitry Andric                                       SrcType, DestType,
17400b57cec5SDimitry Andric                                       Paths.front(),
17410b57cec5SDimitry Andric                                 diag::err_downcast_from_inaccessible_base)) {
17420b57cec5SDimitry Andric     case Sema::AR_accessible:
17430b57cec5SDimitry Andric     case Sema::AR_delayed:     // be optimistic
17440b57cec5SDimitry Andric     case Sema::AR_dependent:   // be optimistic
17450b57cec5SDimitry Andric       break;
17460b57cec5SDimitry Andric 
17470b57cec5SDimitry Andric     case Sema::AR_inaccessible:
17480b57cec5SDimitry Andric       msg = 0;
17490b57cec5SDimitry Andric       return TC_Failed;
17500b57cec5SDimitry Andric     }
17510b57cec5SDimitry Andric   }
17520b57cec5SDimitry Andric 
17530b57cec5SDimitry Andric   Self.BuildBasePathArray(Paths, BasePath);
17540b57cec5SDimitry Andric   Kind = CK_BaseToDerived;
17550b57cec5SDimitry Andric   return TC_Success;
17560b57cec5SDimitry Andric }
17570b57cec5SDimitry Andric 
17580b57cec5SDimitry Andric /// TryStaticMemberPointerUpcast - Tests whether a conversion according to
17590b57cec5SDimitry Andric /// C++ 5.2.9p9 is valid:
17600b57cec5SDimitry Andric ///
17610b57cec5SDimitry Andric ///   An rvalue of type "pointer to member of D of type cv1 T" can be
17620b57cec5SDimitry Andric ///   converted to an rvalue of type "pointer to member of B of type cv2 T",
17630b57cec5SDimitry Andric ///   where B is a base class of D [...].
17640b57cec5SDimitry Andric ///
17650b57cec5SDimitry Andric TryCastResult
17660b57cec5SDimitry Andric TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType,
17670b57cec5SDimitry Andric                              QualType DestType, bool CStyle,
17680b57cec5SDimitry Andric                              SourceRange OpRange,
17690b57cec5SDimitry Andric                              unsigned &msg, CastKind &Kind,
17700b57cec5SDimitry Andric                              CXXCastPath &BasePath) {
17710b57cec5SDimitry Andric   const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>();
17720b57cec5SDimitry Andric   if (!DestMemPtr)
17730b57cec5SDimitry Andric     return TC_NotApplicable;
17740b57cec5SDimitry Andric 
17750b57cec5SDimitry Andric   bool WasOverloadedFunction = false;
17760b57cec5SDimitry Andric   DeclAccessPair FoundOverload;
17770b57cec5SDimitry Andric   if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
17780b57cec5SDimitry Andric     if (FunctionDecl *Fn
17790b57cec5SDimitry Andric           = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), DestType, false,
17800b57cec5SDimitry Andric                                                     FoundOverload)) {
17810b57cec5SDimitry Andric       CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);
17820b57cec5SDimitry Andric       SrcType = Self.Context.getMemberPointerType(Fn->getType(),
17830b57cec5SDimitry Andric                       Self.Context.getTypeDeclType(M->getParent()).getTypePtr());
17840b57cec5SDimitry Andric       WasOverloadedFunction = true;
17850b57cec5SDimitry Andric     }
17860b57cec5SDimitry Andric   }
17870b57cec5SDimitry Andric 
17880b57cec5SDimitry Andric   const MemberPointerType *SrcMemPtr = SrcType->getAs<MemberPointerType>();
17890b57cec5SDimitry Andric   if (!SrcMemPtr) {
17900b57cec5SDimitry Andric     msg = diag::err_bad_static_cast_member_pointer_nonmp;
17910b57cec5SDimitry Andric     return TC_NotApplicable;
17920b57cec5SDimitry Andric   }
17930b57cec5SDimitry Andric 
17940b57cec5SDimitry Andric   // Lock down the inheritance model right now in MS ABI, whether or not the
17950b57cec5SDimitry Andric   // pointee types are the same.
17960b57cec5SDimitry Andric   if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
17970b57cec5SDimitry Andric     (void)Self.isCompleteType(OpRange.getBegin(), SrcType);
17980b57cec5SDimitry Andric     (void)Self.isCompleteType(OpRange.getBegin(), DestType);
17990b57cec5SDimitry Andric   }
18000b57cec5SDimitry Andric 
18010b57cec5SDimitry Andric   // T == T, modulo cv
18020b57cec5SDimitry Andric   if (!Self.Context.hasSameUnqualifiedType(SrcMemPtr->getPointeeType(),
18030b57cec5SDimitry Andric                                            DestMemPtr->getPointeeType()))
18040b57cec5SDimitry Andric     return TC_NotApplicable;
18050b57cec5SDimitry Andric 
18060b57cec5SDimitry Andric   // B base of D
18070b57cec5SDimitry Andric   QualType SrcClass(SrcMemPtr->getClass(), 0);
18080b57cec5SDimitry Andric   QualType DestClass(DestMemPtr->getClass(), 0);
18090b57cec5SDimitry Andric   CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18100b57cec5SDimitry Andric                   /*DetectVirtual=*/true);
18110b57cec5SDimitry Andric   if (!Self.IsDerivedFrom(OpRange.getBegin(), SrcClass, DestClass, Paths))
18120b57cec5SDimitry Andric     return TC_NotApplicable;
18130b57cec5SDimitry Andric 
18140b57cec5SDimitry Andric   // B is a base of D. But is it an allowed base? If not, it's a hard error.
18150b57cec5SDimitry Andric   if (Paths.isAmbiguous(Self.Context.getCanonicalType(DestClass))) {
18160b57cec5SDimitry Andric     Paths.clear();
18170b57cec5SDimitry Andric     Paths.setRecordingPaths(true);
18180b57cec5SDimitry Andric     bool StillOkay =
18190b57cec5SDimitry Andric         Self.IsDerivedFrom(OpRange.getBegin(), SrcClass, DestClass, Paths);
18200b57cec5SDimitry Andric     assert(StillOkay);
18210b57cec5SDimitry Andric     (void)StillOkay;
18220b57cec5SDimitry Andric     std::string PathDisplayStr = Self.getAmbiguousPathsDisplayString(Paths);
18230b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_ambiguous_memptr_conv)
18240b57cec5SDimitry Andric       << 1 << SrcClass << DestClass << PathDisplayStr << OpRange;
18250b57cec5SDimitry Andric     msg = 0;
18260b57cec5SDimitry Andric     return TC_Failed;
18270b57cec5SDimitry Andric   }
18280b57cec5SDimitry Andric 
18290b57cec5SDimitry Andric   if (const RecordType *VBase = Paths.getDetectedVirtual()) {
18300b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_memptr_conv_via_virtual)
18310b57cec5SDimitry Andric       << SrcClass << DestClass << QualType(VBase, 0) << OpRange;
18320b57cec5SDimitry Andric     msg = 0;
18330b57cec5SDimitry Andric     return TC_Failed;
18340b57cec5SDimitry Andric   }
18350b57cec5SDimitry Andric 
18360b57cec5SDimitry Andric   if (!CStyle) {
18370b57cec5SDimitry Andric     switch (Self.CheckBaseClassAccess(OpRange.getBegin(),
18380b57cec5SDimitry Andric                                       DestClass, SrcClass,
18390b57cec5SDimitry Andric                                       Paths.front(),
18400b57cec5SDimitry Andric                                       diag::err_upcast_to_inaccessible_base)) {
18410b57cec5SDimitry Andric     case Sema::AR_accessible:
18420b57cec5SDimitry Andric     case Sema::AR_delayed:
18430b57cec5SDimitry Andric     case Sema::AR_dependent:
18440b57cec5SDimitry Andric       // Optimistically assume that the delayed and dependent cases
18450b57cec5SDimitry Andric       // will work out.
18460b57cec5SDimitry Andric       break;
18470b57cec5SDimitry Andric 
18480b57cec5SDimitry Andric     case Sema::AR_inaccessible:
18490b57cec5SDimitry Andric       msg = 0;
18500b57cec5SDimitry Andric       return TC_Failed;
18510b57cec5SDimitry Andric     }
18520b57cec5SDimitry Andric   }
18530b57cec5SDimitry Andric 
18540b57cec5SDimitry Andric   if (WasOverloadedFunction) {
18550b57cec5SDimitry Andric     // Resolve the address of the overloaded function again, this time
18560b57cec5SDimitry Andric     // allowing complaints if something goes wrong.
18570b57cec5SDimitry Andric     FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),
18580b57cec5SDimitry Andric                                                                DestType,
18590b57cec5SDimitry Andric                                                                true,
18600b57cec5SDimitry Andric                                                                FoundOverload);
18610b57cec5SDimitry Andric     if (!Fn) {
18620b57cec5SDimitry Andric       msg = 0;
18630b57cec5SDimitry Andric       return TC_Failed;
18640b57cec5SDimitry Andric     }
18650b57cec5SDimitry Andric 
18660b57cec5SDimitry Andric     SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn);
18670b57cec5SDimitry Andric     if (!SrcExpr.isUsable()) {
18680b57cec5SDimitry Andric       msg = 0;
18690b57cec5SDimitry Andric       return TC_Failed;
18700b57cec5SDimitry Andric     }
18710b57cec5SDimitry Andric   }
18720b57cec5SDimitry Andric 
18730b57cec5SDimitry Andric   Self.BuildBasePathArray(Paths, BasePath);
18740b57cec5SDimitry Andric   Kind = CK_DerivedToBaseMemberPointer;
18750b57cec5SDimitry Andric   return TC_Success;
18760b57cec5SDimitry Andric }
18770b57cec5SDimitry Andric 
18780b57cec5SDimitry Andric /// TryStaticImplicitCast - Tests whether a conversion according to C++ 5.2.9p2
18790b57cec5SDimitry Andric /// is valid:
18800b57cec5SDimitry Andric ///
18810b57cec5SDimitry Andric ///   An expression e can be explicitly converted to a type T using a
18820b57cec5SDimitry Andric ///   @c static_cast if the declaration "T t(e);" is well-formed [...].
1883*0fca6ea1SDimitry Andric TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr,
1884*0fca6ea1SDimitry Andric                                     QualType DestType,
1885*0fca6ea1SDimitry Andric                                     CheckedConversionKind CCK,
18860b57cec5SDimitry Andric                                     SourceRange OpRange, unsigned &msg,
18870b57cec5SDimitry Andric                                     CastKind &Kind, bool ListInitialization) {
18880b57cec5SDimitry Andric   if (DestType->isRecordType()) {
18890b57cec5SDimitry Andric     if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
1890480093f4SDimitry Andric                                  diag::err_bad_cast_incomplete) ||
18910b57cec5SDimitry Andric         Self.RequireNonAbstractType(OpRange.getBegin(), DestType,
18920b57cec5SDimitry Andric                                     diag::err_allocation_of_abstract_type)) {
18930b57cec5SDimitry Andric       msg = 0;
18940b57cec5SDimitry Andric       return TC_Failed;
18950b57cec5SDimitry Andric     }
18960b57cec5SDimitry Andric   }
18970b57cec5SDimitry Andric 
18980b57cec5SDimitry Andric   InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
1899*0fca6ea1SDimitry Andric   InitializationKind InitKind =
1900*0fca6ea1SDimitry Andric       (CCK == CheckedConversionKind::CStyleCast)
19010b57cec5SDimitry Andric           ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange,
19020b57cec5SDimitry Andric                                                  ListInitialization)
1903*0fca6ea1SDimitry Andric       : (CCK == CheckedConversionKind::FunctionalCast)
1904*0fca6ea1SDimitry Andric           ? InitializationKind::CreateFunctionalCast(OpRange,
1905*0fca6ea1SDimitry Andric                                                      ListInitialization)
19060b57cec5SDimitry Andric           : InitializationKind::CreateCast(OpRange);
19070b57cec5SDimitry Andric   Expr *SrcExprRaw = SrcExpr.get();
19080b57cec5SDimitry Andric   // FIXME: Per DR242, we should check for an implicit conversion sequence
19090b57cec5SDimitry Andric   // or for a constructor that could be invoked by direct-initialization
19100b57cec5SDimitry Andric   // here, not for an initialization sequence.
19110b57cec5SDimitry Andric   InitializationSequence InitSeq(Self, Entity, InitKind, SrcExprRaw);
19120b57cec5SDimitry Andric 
19130b57cec5SDimitry Andric   // At this point of CheckStaticCast, if the destination is a reference,
19140b57cec5SDimitry Andric   // or the expression is an overload expression this has to work.
19150b57cec5SDimitry Andric   // There is no other way that works.
19160b57cec5SDimitry Andric   // On the other hand, if we're checking a C-style cast, we've still got
19170b57cec5SDimitry Andric   // the reinterpret_cast way.
1918*0fca6ea1SDimitry Andric   bool CStyle = (CCK == CheckedConversionKind::CStyleCast ||
1919*0fca6ea1SDimitry Andric                  CCK == CheckedConversionKind::FunctionalCast);
19200b57cec5SDimitry Andric   if (InitSeq.Failed() && (CStyle || !DestType->isReferenceType()))
19210b57cec5SDimitry Andric     return TC_NotApplicable;
19220b57cec5SDimitry Andric 
19230b57cec5SDimitry Andric   ExprResult Result = InitSeq.Perform(Self, Entity, InitKind, SrcExprRaw);
19240b57cec5SDimitry Andric   if (Result.isInvalid()) {
19250b57cec5SDimitry Andric     msg = 0;
19260b57cec5SDimitry Andric     return TC_Failed;
19270b57cec5SDimitry Andric   }
19280b57cec5SDimitry Andric 
19290b57cec5SDimitry Andric   if (InitSeq.isConstructorInitialization())
19300b57cec5SDimitry Andric     Kind = CK_ConstructorConversion;
19310b57cec5SDimitry Andric   else
19320b57cec5SDimitry Andric     Kind = CK_NoOp;
19330b57cec5SDimitry Andric 
19340b57cec5SDimitry Andric   SrcExpr = Result;
19350b57cec5SDimitry Andric   return TC_Success;
19360b57cec5SDimitry Andric }
19370b57cec5SDimitry Andric 
19380b57cec5SDimitry Andric /// TryConstCast - See if a const_cast from source to destination is allowed,
19390b57cec5SDimitry Andric /// and perform it if it is.
19400b57cec5SDimitry Andric static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr,
19410b57cec5SDimitry Andric                                   QualType DestType, bool CStyle,
19420b57cec5SDimitry Andric                                   unsigned &msg) {
19430b57cec5SDimitry Andric   DestType = Self.Context.getCanonicalType(DestType);
19440b57cec5SDimitry Andric   QualType SrcType = SrcExpr.get()->getType();
19450b57cec5SDimitry Andric   bool NeedToMaterializeTemporary = false;
19460b57cec5SDimitry Andric 
19470b57cec5SDimitry Andric   if (const ReferenceType *DestTypeTmp =DestType->getAs<ReferenceType>()) {
19480b57cec5SDimitry Andric     // C++11 5.2.11p4:
19490b57cec5SDimitry Andric     //   if a pointer to T1 can be explicitly converted to the type "pointer to
19500b57cec5SDimitry Andric     //   T2" using a const_cast, then the following conversions can also be
19510b57cec5SDimitry Andric     //   made:
19520b57cec5SDimitry Andric     //    -- an lvalue of type T1 can be explicitly converted to an lvalue of
19530b57cec5SDimitry Andric     //       type T2 using the cast const_cast<T2&>;
19540b57cec5SDimitry Andric     //    -- a glvalue of type T1 can be explicitly converted to an xvalue of
19550b57cec5SDimitry Andric     //       type T2 using the cast const_cast<T2&&>; and
19560b57cec5SDimitry Andric     //    -- if T1 is a class type, a prvalue of type T1 can be explicitly
19570b57cec5SDimitry Andric     //       converted to an xvalue of type T2 using the cast const_cast<T2&&>.
19580b57cec5SDimitry Andric 
19590b57cec5SDimitry Andric     if (isa<LValueReferenceType>(DestTypeTmp) && !SrcExpr.get()->isLValue()) {
19600b57cec5SDimitry Andric       // Cannot const_cast non-lvalue to lvalue reference type. But if this
19610b57cec5SDimitry Andric       // is C-style, static_cast might find a way, so we simply suggest a
19620b57cec5SDimitry Andric       // message and tell the parent to keep searching.
19630b57cec5SDimitry Andric       msg = diag::err_bad_cxx_cast_rvalue;
19640b57cec5SDimitry Andric       return TC_NotApplicable;
19650b57cec5SDimitry Andric     }
19660b57cec5SDimitry Andric 
1967fe6060f1SDimitry Andric     if (isa<RValueReferenceType>(DestTypeTmp) && SrcExpr.get()->isPRValue()) {
19680b57cec5SDimitry Andric       if (!SrcType->isRecordType()) {
19690b57cec5SDimitry Andric         // Cannot const_cast non-class prvalue to rvalue reference type. But if
19700b57cec5SDimitry Andric         // this is C-style, static_cast can do this.
19710b57cec5SDimitry Andric         msg = diag::err_bad_cxx_cast_rvalue;
19720b57cec5SDimitry Andric         return TC_NotApplicable;
19730b57cec5SDimitry Andric       }
19740b57cec5SDimitry Andric 
19750b57cec5SDimitry Andric       // Materialize the class prvalue so that the const_cast can bind a
19760b57cec5SDimitry Andric       // reference to it.
19770b57cec5SDimitry Andric       NeedToMaterializeTemporary = true;
19780b57cec5SDimitry Andric     }
19790b57cec5SDimitry Andric 
19800b57cec5SDimitry Andric     // It's not completely clear under the standard whether we can
19810b57cec5SDimitry Andric     // const_cast bit-field gl-values.  Doing so would not be
19820b57cec5SDimitry Andric     // intrinsically complicated, but for now, we say no for
19830b57cec5SDimitry Andric     // consistency with other compilers and await the word of the
19840b57cec5SDimitry Andric     // committee.
19850b57cec5SDimitry Andric     if (SrcExpr.get()->refersToBitField()) {
19860b57cec5SDimitry Andric       msg = diag::err_bad_cxx_cast_bitfield;
19870b57cec5SDimitry Andric       return TC_NotApplicable;
19880b57cec5SDimitry Andric     }
19890b57cec5SDimitry Andric 
19900b57cec5SDimitry Andric     DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());
19910b57cec5SDimitry Andric     SrcType = Self.Context.getPointerType(SrcType);
19920b57cec5SDimitry Andric   }
19930b57cec5SDimitry Andric 
19940b57cec5SDimitry Andric   // C++ 5.2.11p5: For a const_cast involving pointers to data members [...]
19950b57cec5SDimitry Andric   //   the rules for const_cast are the same as those used for pointers.
19960b57cec5SDimitry Andric 
19970b57cec5SDimitry Andric   if (!DestType->isPointerType() &&
19980b57cec5SDimitry Andric       !DestType->isMemberPointerType() &&
19990b57cec5SDimitry Andric       !DestType->isObjCObjectPointerType()) {
20000b57cec5SDimitry Andric     // Cannot cast to non-pointer, non-reference type. Note that, if DestType
20010b57cec5SDimitry Andric     // was a reference type, we converted it to a pointer above.
20020b57cec5SDimitry Andric     // The status of rvalue references isn't entirely clear, but it looks like
20030b57cec5SDimitry Andric     // conversion to them is simply invalid.
20040b57cec5SDimitry Andric     // C++ 5.2.11p3: For two pointer types [...]
20050b57cec5SDimitry Andric     if (!CStyle)
20060b57cec5SDimitry Andric       msg = diag::err_bad_const_cast_dest;
20070b57cec5SDimitry Andric     return TC_NotApplicable;
20080b57cec5SDimitry Andric   }
20090b57cec5SDimitry Andric   if (DestType->isFunctionPointerType() ||
20100b57cec5SDimitry Andric       DestType->isMemberFunctionPointerType()) {
20110b57cec5SDimitry Andric     // Cannot cast direct function pointers.
20120b57cec5SDimitry Andric     // C++ 5.2.11p2: [...] where T is any object type or the void type [...]
20130b57cec5SDimitry Andric     // T is the ultimate pointee of source and target type.
20140b57cec5SDimitry Andric     if (!CStyle)
20150b57cec5SDimitry Andric       msg = diag::err_bad_const_cast_dest;
20160b57cec5SDimitry Andric     return TC_NotApplicable;
20170b57cec5SDimitry Andric   }
20180b57cec5SDimitry Andric 
20190b57cec5SDimitry Andric   // C++ [expr.const.cast]p3:
20200b57cec5SDimitry Andric   //   "For two similar types T1 and T2, [...]"
20210b57cec5SDimitry Andric   //
20220b57cec5SDimitry Andric   // We only allow a const_cast to change cvr-qualifiers, not other kinds of
20230b57cec5SDimitry Andric   // type qualifiers. (Likewise, we ignore other changes when determining
20240b57cec5SDimitry Andric   // whether a cast casts away constness.)
20250b57cec5SDimitry Andric   if (!Self.Context.hasCvrSimilarType(SrcType, DestType))
20260b57cec5SDimitry Andric     return TC_NotApplicable;
20270b57cec5SDimitry Andric 
20280b57cec5SDimitry Andric   if (NeedToMaterializeTemporary)
20290b57cec5SDimitry Andric     // This is a const_cast from a class prvalue to an rvalue reference type.
20300b57cec5SDimitry Andric     // Materialize a temporary to store the result of the conversion.
20310b57cec5SDimitry Andric     SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcExpr.get()->getType(),
20320b57cec5SDimitry Andric                                                   SrcExpr.get(),
20330b57cec5SDimitry Andric                                                   /*IsLValueReference*/ false);
20340b57cec5SDimitry Andric 
20350b57cec5SDimitry Andric   return TC_Success;
20360b57cec5SDimitry Andric }
20370b57cec5SDimitry Andric 
20380b57cec5SDimitry Andric // Checks for undefined behavior in reinterpret_cast.
20390b57cec5SDimitry Andric // The cases that is checked for is:
20400b57cec5SDimitry Andric // *reinterpret_cast<T*>(&a)
20410b57cec5SDimitry Andric // reinterpret_cast<T&>(a)
20420b57cec5SDimitry Andric // where accessing 'a' as type 'T' will result in undefined behavior.
20430b57cec5SDimitry Andric void Sema::CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
20440b57cec5SDimitry Andric                                           bool IsDereference,
20450b57cec5SDimitry Andric                                           SourceRange Range) {
20460b57cec5SDimitry Andric   unsigned DiagID = IsDereference ?
20470b57cec5SDimitry Andric                         diag::warn_pointer_indirection_from_incompatible_type :
20480b57cec5SDimitry Andric                         diag::warn_undefined_reinterpret_cast;
20490b57cec5SDimitry Andric 
20500b57cec5SDimitry Andric   if (Diags.isIgnored(DiagID, Range.getBegin()))
20510b57cec5SDimitry Andric     return;
20520b57cec5SDimitry Andric 
20530b57cec5SDimitry Andric   QualType SrcTy, DestTy;
20540b57cec5SDimitry Andric   if (IsDereference) {
20550b57cec5SDimitry Andric     if (!SrcType->getAs<PointerType>() || !DestType->getAs<PointerType>()) {
20560b57cec5SDimitry Andric       return;
20570b57cec5SDimitry Andric     }
20580b57cec5SDimitry Andric     SrcTy = SrcType->getPointeeType();
20590b57cec5SDimitry Andric     DestTy = DestType->getPointeeType();
20600b57cec5SDimitry Andric   } else {
20610b57cec5SDimitry Andric     if (!DestType->getAs<ReferenceType>()) {
20620b57cec5SDimitry Andric       return;
20630b57cec5SDimitry Andric     }
20640b57cec5SDimitry Andric     SrcTy = SrcType;
20650b57cec5SDimitry Andric     DestTy = DestType->getPointeeType();
20660b57cec5SDimitry Andric   }
20670b57cec5SDimitry Andric 
20680b57cec5SDimitry Andric   // Cast is compatible if the types are the same.
20690b57cec5SDimitry Andric   if (Context.hasSameUnqualifiedType(DestTy, SrcTy)) {
20700b57cec5SDimitry Andric     return;
20710b57cec5SDimitry Andric   }
20720b57cec5SDimitry Andric   // or one of the types is a char or void type
20730b57cec5SDimitry Andric   if (DestTy->isAnyCharacterType() || DestTy->isVoidType() ||
20740b57cec5SDimitry Andric       SrcTy->isAnyCharacterType() || SrcTy->isVoidType()) {
20750b57cec5SDimitry Andric     return;
20760b57cec5SDimitry Andric   }
20770b57cec5SDimitry Andric   // or one of the types is a tag type.
20780b57cec5SDimitry Andric   if (SrcTy->getAs<TagType>() || DestTy->getAs<TagType>()) {
20790b57cec5SDimitry Andric     return;
20800b57cec5SDimitry Andric   }
20810b57cec5SDimitry Andric 
20820b57cec5SDimitry Andric   // FIXME: Scoped enums?
20830b57cec5SDimitry Andric   if ((SrcTy->isUnsignedIntegerType() && DestTy->isSignedIntegerType()) ||
20840b57cec5SDimitry Andric       (SrcTy->isSignedIntegerType() && DestTy->isUnsignedIntegerType())) {
20850b57cec5SDimitry Andric     if (Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy)) {
20860b57cec5SDimitry Andric       return;
20870b57cec5SDimitry Andric     }
20880b57cec5SDimitry Andric   }
20890b57cec5SDimitry Andric 
20900b57cec5SDimitry Andric   Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range;
20910b57cec5SDimitry Andric }
20920b57cec5SDimitry Andric 
20930b57cec5SDimitry Andric static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr,
20940b57cec5SDimitry Andric                                   QualType DestType) {
20950b57cec5SDimitry Andric   QualType SrcType = SrcExpr.get()->getType();
20960b57cec5SDimitry Andric   if (Self.Context.hasSameType(SrcType, DestType))
20970b57cec5SDimitry Andric     return;
20980b57cec5SDimitry Andric   if (const PointerType *SrcPtrTy = SrcType->getAs<PointerType>())
20990b57cec5SDimitry Andric     if (SrcPtrTy->isObjCSelType()) {
21000b57cec5SDimitry Andric       QualType DT = DestType;
21010b57cec5SDimitry Andric       if (isa<PointerType>(DestType))
21020b57cec5SDimitry Andric         DT = DestType->getPointeeType();
21030b57cec5SDimitry Andric       if (!DT.getUnqualifiedType()->isVoidType())
21040b57cec5SDimitry Andric         Self.Diag(SrcExpr.get()->getExprLoc(),
21050b57cec5SDimitry Andric                   diag::warn_cast_pointer_from_sel)
21060b57cec5SDimitry Andric         << SrcType << DestType << SrcExpr.get()->getSourceRange();
21070b57cec5SDimitry Andric     }
21080b57cec5SDimitry Andric }
21090b57cec5SDimitry Andric 
21100b57cec5SDimitry Andric /// Diagnose casts that change the calling convention of a pointer to a function
21110b57cec5SDimitry Andric /// defined in the current TU.
21120b57cec5SDimitry Andric static void DiagnoseCallingConvCast(Sema &Self, const ExprResult &SrcExpr,
21130b57cec5SDimitry Andric                                     QualType DstType, SourceRange OpRange) {
21140b57cec5SDimitry Andric   // Check if this cast would change the calling convention of a function
21150b57cec5SDimitry Andric   // pointer type.
21160b57cec5SDimitry Andric   QualType SrcType = SrcExpr.get()->getType();
21170b57cec5SDimitry Andric   if (Self.Context.hasSameType(SrcType, DstType) ||
21180b57cec5SDimitry Andric       !SrcType->isFunctionPointerType() || !DstType->isFunctionPointerType())
21190b57cec5SDimitry Andric     return;
21200b57cec5SDimitry Andric   const auto *SrcFTy =
21210b57cec5SDimitry Andric       SrcType->castAs<PointerType>()->getPointeeType()->castAs<FunctionType>();
21220b57cec5SDimitry Andric   const auto *DstFTy =
21230b57cec5SDimitry Andric       DstType->castAs<PointerType>()->getPointeeType()->castAs<FunctionType>();
21240b57cec5SDimitry Andric   CallingConv SrcCC = SrcFTy->getCallConv();
21250b57cec5SDimitry Andric   CallingConv DstCC = DstFTy->getCallConv();
21260b57cec5SDimitry Andric   if (SrcCC == DstCC)
21270b57cec5SDimitry Andric     return;
21280b57cec5SDimitry Andric 
21290b57cec5SDimitry Andric   // We have a calling convention cast. Check if the source is a pointer to a
21300b57cec5SDimitry Andric   // known, specific function that has already been defined.
21310b57cec5SDimitry Andric   Expr *Src = SrcExpr.get()->IgnoreParenImpCasts();
21320b57cec5SDimitry Andric   if (auto *UO = dyn_cast<UnaryOperator>(Src))
21330b57cec5SDimitry Andric     if (UO->getOpcode() == UO_AddrOf)
21340b57cec5SDimitry Andric       Src = UO->getSubExpr()->IgnoreParenImpCasts();
21350b57cec5SDimitry Andric   auto *DRE = dyn_cast<DeclRefExpr>(Src);
21360b57cec5SDimitry Andric   if (!DRE)
21370b57cec5SDimitry Andric     return;
21380b57cec5SDimitry Andric   auto *FD = dyn_cast<FunctionDecl>(DRE->getDecl());
21390b57cec5SDimitry Andric   if (!FD)
21400b57cec5SDimitry Andric     return;
21410b57cec5SDimitry Andric 
21420b57cec5SDimitry Andric   // Only warn if we are casting from the default convention to a non-default
21430b57cec5SDimitry Andric   // convention. This can happen when the programmer forgot to apply the calling
21440b57cec5SDimitry Andric   // convention to the function declaration and then inserted this cast to
21450b57cec5SDimitry Andric   // satisfy the type system.
21460b57cec5SDimitry Andric   CallingConv DefaultCC = Self.getASTContext().getDefaultCallingConvention(
21470b57cec5SDimitry Andric       FD->isVariadic(), FD->isCXXInstanceMember());
21480b57cec5SDimitry Andric   if (DstCC == DefaultCC || SrcCC != DefaultCC)
21490b57cec5SDimitry Andric     return;
21500b57cec5SDimitry Andric 
21510b57cec5SDimitry Andric   // Diagnose this cast, as it is probably bad.
21520b57cec5SDimitry Andric   StringRef SrcCCName = FunctionType::getNameForCallConv(SrcCC);
21530b57cec5SDimitry Andric   StringRef DstCCName = FunctionType::getNameForCallConv(DstCC);
21540b57cec5SDimitry Andric   Self.Diag(OpRange.getBegin(), diag::warn_cast_calling_conv)
21550b57cec5SDimitry Andric       << SrcCCName << DstCCName << OpRange;
21560b57cec5SDimitry Andric 
21570b57cec5SDimitry Andric   // The checks above are cheaper than checking if the diagnostic is enabled.
21580b57cec5SDimitry Andric   // However, it's worth checking if the warning is enabled before we construct
21590b57cec5SDimitry Andric   // a fixit.
21600b57cec5SDimitry Andric   if (Self.Diags.isIgnored(diag::warn_cast_calling_conv, OpRange.getBegin()))
21610b57cec5SDimitry Andric     return;
21620b57cec5SDimitry Andric 
21630b57cec5SDimitry Andric   // Try to suggest a fixit to change the calling convention of the function
21640b57cec5SDimitry Andric   // whose address was taken. Try to use the latest macro for the convention.
21650b57cec5SDimitry Andric   // For example, users probably want to write "WINAPI" instead of "__stdcall"
21660b57cec5SDimitry Andric   // to match the Windows header declarations.
21670b57cec5SDimitry Andric   SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc();
21680b57cec5SDimitry Andric   Preprocessor &PP = Self.getPreprocessor();
21690b57cec5SDimitry Andric   SmallVector<TokenValue, 6> AttrTokens;
21700b57cec5SDimitry Andric   SmallString<64> CCAttrText;
21710b57cec5SDimitry Andric   llvm::raw_svector_ostream OS(CCAttrText);
21720b57cec5SDimitry Andric   if (Self.getLangOpts().MicrosoftExt) {
21730b57cec5SDimitry Andric     // __stdcall or __vectorcall
21740b57cec5SDimitry Andric     OS << "__" << DstCCName;
21750b57cec5SDimitry Andric     IdentifierInfo *II = PP.getIdentifierInfo(OS.str());
21760b57cec5SDimitry Andric     AttrTokens.push_back(II->isKeyword(Self.getLangOpts())
21770b57cec5SDimitry Andric                              ? TokenValue(II->getTokenID())
21780b57cec5SDimitry Andric                              : TokenValue(II));
21790b57cec5SDimitry Andric   } else {
21800b57cec5SDimitry Andric     // __attribute__((stdcall)) or __attribute__((vectorcall))
21810b57cec5SDimitry Andric     OS << "__attribute__((" << DstCCName << "))";
21820b57cec5SDimitry Andric     AttrTokens.push_back(tok::kw___attribute);
21830b57cec5SDimitry Andric     AttrTokens.push_back(tok::l_paren);
21840b57cec5SDimitry Andric     AttrTokens.push_back(tok::l_paren);
21850b57cec5SDimitry Andric     IdentifierInfo *II = PP.getIdentifierInfo(DstCCName);
21860b57cec5SDimitry Andric     AttrTokens.push_back(II->isKeyword(Self.getLangOpts())
21870b57cec5SDimitry Andric                              ? TokenValue(II->getTokenID())
21880b57cec5SDimitry Andric                              : TokenValue(II));
21890b57cec5SDimitry Andric     AttrTokens.push_back(tok::r_paren);
21900b57cec5SDimitry Andric     AttrTokens.push_back(tok::r_paren);
21910b57cec5SDimitry Andric   }
21920b57cec5SDimitry Andric   StringRef AttrSpelling = PP.getLastMacroWithSpelling(NameLoc, AttrTokens);
21930b57cec5SDimitry Andric   if (!AttrSpelling.empty())
21940b57cec5SDimitry Andric     CCAttrText = AttrSpelling;
21950b57cec5SDimitry Andric   OS << ' ';
21960b57cec5SDimitry Andric   Self.Diag(NameLoc, diag::note_change_calling_conv_fixit)
21970b57cec5SDimitry Andric       << FD << DstCCName << FixItHint::CreateInsertion(NameLoc, CCAttrText);
21980b57cec5SDimitry Andric }
21990b57cec5SDimitry Andric 
22005ffd83dbSDimitry Andric static void checkIntToPointerCast(bool CStyle, const SourceRange &OpRange,
22010b57cec5SDimitry Andric                                   const Expr *SrcExpr, QualType DestType,
22020b57cec5SDimitry Andric                                   Sema &Self) {
22030b57cec5SDimitry Andric   QualType SrcType = SrcExpr->getType();
22040b57cec5SDimitry Andric 
22050b57cec5SDimitry Andric   // Not warning on reinterpret_cast, boolean, constant expressions, etc
22060b57cec5SDimitry Andric   // are not explicit design choices, but consistent with GCC's behavior.
22070b57cec5SDimitry Andric   // Feel free to modify them if you've reason/evidence for an alternative.
22080b57cec5SDimitry Andric   if (CStyle && SrcType->isIntegralType(Self.Context)
22090b57cec5SDimitry Andric       && !SrcType->isBooleanType()
22100b57cec5SDimitry Andric       && !SrcType->isEnumeralType()
22110b57cec5SDimitry Andric       && !SrcExpr->isIntegerConstantExpr(Self.Context)
22120b57cec5SDimitry Andric       && Self.Context.getTypeSize(DestType) >
22130b57cec5SDimitry Andric          Self.Context.getTypeSize(SrcType)) {
22140b57cec5SDimitry Andric     // Separate between casts to void* and non-void* pointers.
22150b57cec5SDimitry Andric     // Some APIs use (abuse) void* for something like a user context,
22160b57cec5SDimitry Andric     // and often that value is an integer even if it isn't a pointer itself.
22170b57cec5SDimitry Andric     // Having a separate warning flag allows users to control the warning
22180b57cec5SDimitry Andric     // for their workflow.
22190b57cec5SDimitry Andric     unsigned Diag = DestType->isVoidPointerType() ?
22200b57cec5SDimitry Andric                       diag::warn_int_to_void_pointer_cast
22210b57cec5SDimitry Andric                     : diag::warn_int_to_pointer_cast;
22225ffd83dbSDimitry Andric     Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;
22230b57cec5SDimitry Andric   }
22240b57cec5SDimitry Andric }
22250b57cec5SDimitry Andric 
22260b57cec5SDimitry Andric static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType,
22270b57cec5SDimitry Andric                                              ExprResult &Result) {
22280b57cec5SDimitry Andric   // We can only fix an overloaded reinterpret_cast if
22290b57cec5SDimitry Andric   // - it is a template with explicit arguments that resolves to an lvalue
22300b57cec5SDimitry Andric   //   unambiguously, or
22310b57cec5SDimitry Andric   // - it is the only function in an overload set that may have its address
22320b57cec5SDimitry Andric   //   taken.
22330b57cec5SDimitry Andric 
22340b57cec5SDimitry Andric   Expr *E = Result.get();
22350b57cec5SDimitry Andric   // TODO: what if this fails because of DiagnoseUseOfDecl or something
22360b57cec5SDimitry Andric   // like it?
22370b57cec5SDimitry Andric   if (Self.ResolveAndFixSingleFunctionTemplateSpecialization(
22380b57cec5SDimitry Andric           Result,
2239fe6060f1SDimitry Andric           Expr::getValueKindForType(DestType) ==
2240fe6060f1SDimitry Andric               VK_PRValue // Convert Fun to Ptr
22410b57cec5SDimitry Andric           ) &&
22420b57cec5SDimitry Andric       Result.isUsable())
22430b57cec5SDimitry Andric     return true;
22440b57cec5SDimitry Andric 
22450b57cec5SDimitry Andric   // No guarantees that ResolveAndFixSingleFunctionTemplateSpecialization
22460b57cec5SDimitry Andric   // preserves Result.
22470b57cec5SDimitry Andric   Result = E;
2248480093f4SDimitry Andric   if (!Self.resolveAndFixAddressOfSingleOverloadCandidate(
22490b57cec5SDimitry Andric           Result, /*DoFunctionPointerConversion=*/true))
22500b57cec5SDimitry Andric     return false;
22510b57cec5SDimitry Andric   return Result.isUsable();
22520b57cec5SDimitry Andric }
22530b57cec5SDimitry Andric 
22540b57cec5SDimitry Andric static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
22550b57cec5SDimitry Andric                                         QualType DestType, bool CStyle,
22560b57cec5SDimitry Andric                                         SourceRange OpRange,
22570b57cec5SDimitry Andric                                         unsigned &msg,
22580b57cec5SDimitry Andric                                         CastKind &Kind) {
22590b57cec5SDimitry Andric   bool IsLValueCast = false;
22600b57cec5SDimitry Andric 
22610b57cec5SDimitry Andric   DestType = Self.Context.getCanonicalType(DestType);
22620b57cec5SDimitry Andric   QualType SrcType = SrcExpr.get()->getType();
22630b57cec5SDimitry Andric 
22640b57cec5SDimitry Andric   // Is the source an overloaded name? (i.e. &foo)
22650b57cec5SDimitry Andric   // If so, reinterpret_cast generally can not help us here (13.4, p1, bullet 5)
22660b57cec5SDimitry Andric   if (SrcType == Self.Context.OverloadTy) {
22670b57cec5SDimitry Andric     ExprResult FixedExpr = SrcExpr;
22680b57cec5SDimitry Andric     if (!fixOverloadedReinterpretCastExpr(Self, DestType, FixedExpr))
22690b57cec5SDimitry Andric       return TC_NotApplicable;
22700b57cec5SDimitry Andric 
22710b57cec5SDimitry Andric     assert(FixedExpr.isUsable() && "Invalid result fixing overloaded expr");
22720b57cec5SDimitry Andric     SrcExpr = FixedExpr;
22730b57cec5SDimitry Andric     SrcType = SrcExpr.get()->getType();
22740b57cec5SDimitry Andric   }
22750b57cec5SDimitry Andric 
22760b57cec5SDimitry Andric   if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {
22770b57cec5SDimitry Andric     if (!SrcExpr.get()->isGLValue()) {
22780b57cec5SDimitry Andric       // Cannot cast non-glvalue to (lvalue or rvalue) reference type. See the
22790b57cec5SDimitry Andric       // similar comment in const_cast.
22800b57cec5SDimitry Andric       msg = diag::err_bad_cxx_cast_rvalue;
22810b57cec5SDimitry Andric       return TC_NotApplicable;
22820b57cec5SDimitry Andric     }
22830b57cec5SDimitry Andric 
22840b57cec5SDimitry Andric     if (!CStyle) {
22850b57cec5SDimitry Andric       Self.CheckCompatibleReinterpretCast(SrcType, DestType,
22860b57cec5SDimitry Andric                                           /*IsDereference=*/false, OpRange);
22870b57cec5SDimitry Andric     }
22880b57cec5SDimitry Andric 
22890b57cec5SDimitry Andric     // C++ 5.2.10p10: [...] a reference cast reinterpret_cast<T&>(x) has the
22900b57cec5SDimitry Andric     //   same effect as the conversion *reinterpret_cast<T*>(&x) with the
22910b57cec5SDimitry Andric     //   built-in & and * operators.
22920b57cec5SDimitry Andric 
22930b57cec5SDimitry Andric     const char *inappropriate = nullptr;
22940b57cec5SDimitry Andric     switch (SrcExpr.get()->getObjectKind()) {
22950b57cec5SDimitry Andric     case OK_Ordinary:
22960b57cec5SDimitry Andric       break;
22970b57cec5SDimitry Andric     case OK_BitField:
22980b57cec5SDimitry Andric       msg = diag::err_bad_cxx_cast_bitfield;
22990b57cec5SDimitry Andric       return TC_NotApplicable;
23000b57cec5SDimitry Andric       // FIXME: Use a specific diagnostic for the rest of these cases.
23010b57cec5SDimitry Andric     case OK_VectorComponent: inappropriate = "vector element";      break;
23025ffd83dbSDimitry Andric     case OK_MatrixComponent:
23035ffd83dbSDimitry Andric       inappropriate = "matrix element";
23045ffd83dbSDimitry Andric       break;
23050b57cec5SDimitry Andric     case OK_ObjCProperty:    inappropriate = "property expression"; break;
23060b57cec5SDimitry Andric     case OK_ObjCSubscript:   inappropriate = "container subscripting expression";
23070b57cec5SDimitry Andric                              break;
23080b57cec5SDimitry Andric     }
23090b57cec5SDimitry Andric     if (inappropriate) {
23100b57cec5SDimitry Andric       Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_reference)
23110b57cec5SDimitry Andric           << inappropriate << DestType
23120b57cec5SDimitry Andric           << OpRange << SrcExpr.get()->getSourceRange();
23130b57cec5SDimitry Andric       msg = 0; SrcExpr = ExprError();
23140b57cec5SDimitry Andric       return TC_NotApplicable;
23150b57cec5SDimitry Andric     }
23160b57cec5SDimitry Andric 
23170b57cec5SDimitry Andric     // This code does this transformation for the checked types.
23180b57cec5SDimitry Andric     DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());
23190b57cec5SDimitry Andric     SrcType = Self.Context.getPointerType(SrcType);
23200b57cec5SDimitry Andric 
23210b57cec5SDimitry Andric     IsLValueCast = true;
23220b57cec5SDimitry Andric   }
23230b57cec5SDimitry Andric 
23240b57cec5SDimitry Andric   // Canonicalize source for comparison.
23250b57cec5SDimitry Andric   SrcType = Self.Context.getCanonicalType(SrcType);
23260b57cec5SDimitry Andric 
23270b57cec5SDimitry Andric   const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>(),
23280b57cec5SDimitry Andric                           *SrcMemPtr = SrcType->getAs<MemberPointerType>();
23290b57cec5SDimitry Andric   if (DestMemPtr && SrcMemPtr) {
23300b57cec5SDimitry Andric     // C++ 5.2.10p9: An rvalue of type "pointer to member of X of type T1"
23310b57cec5SDimitry Andric     //   can be explicitly converted to an rvalue of type "pointer to member
23320b57cec5SDimitry Andric     //   of Y of type T2" if T1 and T2 are both function types or both object
23330b57cec5SDimitry Andric     //   types.
23340b57cec5SDimitry Andric     if (DestMemPtr->isMemberFunctionPointer() !=
23350b57cec5SDimitry Andric         SrcMemPtr->isMemberFunctionPointer())
23360b57cec5SDimitry Andric       return TC_NotApplicable;
23370b57cec5SDimitry Andric 
23380b57cec5SDimitry Andric     if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
23390b57cec5SDimitry Andric       // We need to determine the inheritance model that the class will use if
23400b57cec5SDimitry Andric       // haven't yet.
23410b57cec5SDimitry Andric       (void)Self.isCompleteType(OpRange.getBegin(), SrcType);
23420b57cec5SDimitry Andric       (void)Self.isCompleteType(OpRange.getBegin(), DestType);
23430b57cec5SDimitry Andric     }
23440b57cec5SDimitry Andric 
23450b57cec5SDimitry Andric     // Don't allow casting between member pointers of different sizes.
23460b57cec5SDimitry Andric     if (Self.Context.getTypeSize(DestMemPtr) !=
23470b57cec5SDimitry Andric         Self.Context.getTypeSize(SrcMemPtr)) {
23480b57cec5SDimitry Andric       msg = diag::err_bad_cxx_cast_member_pointer_size;
23490b57cec5SDimitry Andric       return TC_Failed;
23500b57cec5SDimitry Andric     }
23510b57cec5SDimitry Andric 
23520b57cec5SDimitry Andric     // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away
23530b57cec5SDimitry Andric     //   constness.
23540b57cec5SDimitry Andric     // A reinterpret_cast followed by a const_cast can, though, so in C-style,
23550b57cec5SDimitry Andric     // we accept it.
23560b57cec5SDimitry Andric     if (auto CACK =
23570b57cec5SDimitry Andric             CastsAwayConstness(Self, SrcType, DestType, /*CheckCVR=*/!CStyle,
23580b57cec5SDimitry Andric                                /*CheckObjCLifetime=*/CStyle))
23590b57cec5SDimitry Andric       return getCastAwayConstnessCastKind(CACK, msg);
23600b57cec5SDimitry Andric 
23610b57cec5SDimitry Andric     // A valid member pointer cast.
23620b57cec5SDimitry Andric     assert(!IsLValueCast);
23630b57cec5SDimitry Andric     Kind = CK_ReinterpretMemberPointer;
23640b57cec5SDimitry Andric     return TC_Success;
23650b57cec5SDimitry Andric   }
23660b57cec5SDimitry Andric 
23670b57cec5SDimitry Andric   // See below for the enumeral issue.
23680b57cec5SDimitry Andric   if (SrcType->isNullPtrType() && DestType->isIntegralType(Self.Context)) {
23690b57cec5SDimitry Andric     // C++0x 5.2.10p4: A pointer can be explicitly converted to any integral
23700b57cec5SDimitry Andric     //   type large enough to hold it. A value of std::nullptr_t can be
23710b57cec5SDimitry Andric     //   converted to an integral type; the conversion has the same meaning
23720b57cec5SDimitry Andric     //   and validity as a conversion of (void*)0 to the integral type.
23730b57cec5SDimitry Andric     if (Self.Context.getTypeSize(SrcType) >
23740b57cec5SDimitry Andric         Self.Context.getTypeSize(DestType)) {
23750b57cec5SDimitry Andric       msg = diag::err_bad_reinterpret_cast_small_int;
23760b57cec5SDimitry Andric       return TC_Failed;
23770b57cec5SDimitry Andric     }
23780b57cec5SDimitry Andric     Kind = CK_PointerToIntegral;
23790b57cec5SDimitry Andric     return TC_Success;
23800b57cec5SDimitry Andric   }
23810b57cec5SDimitry Andric 
23820b57cec5SDimitry Andric   // Allow reinterpret_casts between vectors of the same size and
23830b57cec5SDimitry Andric   // between vectors and integers of the same size.
23840b57cec5SDimitry Andric   bool destIsVector = DestType->isVectorType();
23850b57cec5SDimitry Andric   bool srcIsVector = SrcType->isVectorType();
23860b57cec5SDimitry Andric   if (srcIsVector || destIsVector) {
2387e8d8bef9SDimitry Andric     // Allow bitcasting between SVE VLATs and VLSTs, and vice-versa.
2388e8d8bef9SDimitry Andric     if (Self.isValidSveBitcast(SrcType, DestType)) {
2389e8d8bef9SDimitry Andric       Kind = CK_BitCast;
2390e8d8bef9SDimitry Andric       return TC_Success;
2391e8d8bef9SDimitry Andric     }
2392e8d8bef9SDimitry Andric 
239306c3fb27SDimitry Andric     // Allow bitcasting between SVE VLATs and VLSTs, and vice-versa.
2394*0fca6ea1SDimitry Andric     if (Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
239506c3fb27SDimitry Andric       Kind = CK_BitCast;
239606c3fb27SDimitry Andric       return TC_Success;
239706c3fb27SDimitry Andric     }
239806c3fb27SDimitry Andric 
23990b57cec5SDimitry Andric     // The non-vector type, if any, must have integral type.  This is
24000b57cec5SDimitry Andric     // the same rule that C vector casts use; note, however, that enum
24010b57cec5SDimitry Andric     // types are not integral in C++.
24020b57cec5SDimitry Andric     if ((!destIsVector && !DestType->isIntegralType(Self.Context)) ||
24030b57cec5SDimitry Andric         (!srcIsVector && !SrcType->isIntegralType(Self.Context)))
24040b57cec5SDimitry Andric       return TC_NotApplicable;
24050b57cec5SDimitry Andric 
24060b57cec5SDimitry Andric     // The size we want to consider is eltCount * eltSize.
24070b57cec5SDimitry Andric     // That's exactly what the lax-conversion rules will check.
24080b57cec5SDimitry Andric     if (Self.areLaxCompatibleVectorTypes(SrcType, DestType)) {
24090b57cec5SDimitry Andric       Kind = CK_BitCast;
24100b57cec5SDimitry Andric       return TC_Success;
24110b57cec5SDimitry Andric     }
24120b57cec5SDimitry Andric 
2413fe6060f1SDimitry Andric     if (Self.LangOpts.OpenCL && !CStyle) {
2414fe6060f1SDimitry Andric       if (DestType->isExtVectorType() || SrcType->isExtVectorType()) {
2415fe6060f1SDimitry Andric         // FIXME: Allow for reinterpret cast between 3 and 4 element vectors
2416fe6060f1SDimitry Andric         if (Self.areVectorTypesSameSize(SrcType, DestType)) {
2417fe6060f1SDimitry Andric           Kind = CK_BitCast;
2418fe6060f1SDimitry Andric           return TC_Success;
2419fe6060f1SDimitry Andric         }
2420fe6060f1SDimitry Andric       }
2421fe6060f1SDimitry Andric     }
2422fe6060f1SDimitry Andric 
24230b57cec5SDimitry Andric     // Otherwise, pick a reasonable diagnostic.
24240b57cec5SDimitry Andric     if (!destIsVector)
24250b57cec5SDimitry Andric       msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;
24260b57cec5SDimitry Andric     else if (!srcIsVector)
24270b57cec5SDimitry Andric       msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;
24280b57cec5SDimitry Andric     else
24290b57cec5SDimitry Andric       msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;
24300b57cec5SDimitry Andric 
24310b57cec5SDimitry Andric     return TC_Failed;
24320b57cec5SDimitry Andric   }
24330b57cec5SDimitry Andric 
24340b57cec5SDimitry Andric   if (SrcType == DestType) {
24350b57cec5SDimitry Andric     // C++ 5.2.10p2 has a note that mentions that, subject to all other
24360b57cec5SDimitry Andric     // restrictions, a cast to the same type is allowed so long as it does not
24370b57cec5SDimitry Andric     // cast away constness. In C++98, the intent was not entirely clear here,
24380b57cec5SDimitry Andric     // since all other paragraphs explicitly forbid casts to the same type.
24390b57cec5SDimitry Andric     // C++11 clarifies this case with p2.
24400b57cec5SDimitry Andric     //
24410b57cec5SDimitry Andric     // The only allowed types are: integral, enumeration, pointer, or
24420b57cec5SDimitry Andric     // pointer-to-member types.  We also won't restrict Obj-C pointers either.
24430b57cec5SDimitry Andric     Kind = CK_NoOp;
24440b57cec5SDimitry Andric     TryCastResult Result = TC_NotApplicable;
24450b57cec5SDimitry Andric     if (SrcType->isIntegralOrEnumerationType() ||
24460b57cec5SDimitry Andric         SrcType->isAnyPointerType() ||
24470b57cec5SDimitry Andric         SrcType->isMemberPointerType() ||
24480b57cec5SDimitry Andric         SrcType->isBlockPointerType()) {
24490b57cec5SDimitry Andric       Result = TC_Success;
24500b57cec5SDimitry Andric     }
24510b57cec5SDimitry Andric     return Result;
24520b57cec5SDimitry Andric   }
24530b57cec5SDimitry Andric 
24540b57cec5SDimitry Andric   bool destIsPtr = DestType->isAnyPointerType() ||
24550b57cec5SDimitry Andric                    DestType->isBlockPointerType();
24560b57cec5SDimitry Andric   bool srcIsPtr = SrcType->isAnyPointerType() ||
24570b57cec5SDimitry Andric                   SrcType->isBlockPointerType();
24580b57cec5SDimitry Andric   if (!destIsPtr && !srcIsPtr) {
24590b57cec5SDimitry Andric     // Except for std::nullptr_t->integer and lvalue->reference, which are
24600b57cec5SDimitry Andric     // handled above, at least one of the two arguments must be a pointer.
24610b57cec5SDimitry Andric     return TC_NotApplicable;
24620b57cec5SDimitry Andric   }
24630b57cec5SDimitry Andric 
24640b57cec5SDimitry Andric   if (DestType->isIntegralType(Self.Context)) {
24650b57cec5SDimitry Andric     assert(srcIsPtr && "One type must be a pointer");
24660b57cec5SDimitry Andric     // C++ 5.2.10p4: A pointer can be explicitly converted to any integral
24670b57cec5SDimitry Andric     //   type large enough to hold it; except in Microsoft mode, where the
24680b57cec5SDimitry Andric     //   integral type size doesn't matter (except we don't allow bool).
24690b57cec5SDimitry Andric     if ((Self.Context.getTypeSize(SrcType) >
24705ffd83dbSDimitry Andric          Self.Context.getTypeSize(DestType))) {
24715ffd83dbSDimitry Andric       bool MicrosoftException =
24725ffd83dbSDimitry Andric           Self.getLangOpts().MicrosoftExt && !DestType->isBooleanType();
24735ffd83dbSDimitry Andric       if (MicrosoftException) {
24745ffd83dbSDimitry Andric         unsigned Diag = SrcType->isVoidPointerType()
24755ffd83dbSDimitry Andric                             ? diag::warn_void_pointer_to_int_cast
24765ffd83dbSDimitry Andric                             : diag::warn_pointer_to_int_cast;
24775ffd83dbSDimitry Andric         Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;
24785ffd83dbSDimitry Andric       } else {
24790b57cec5SDimitry Andric         msg = diag::err_bad_reinterpret_cast_small_int;
24800b57cec5SDimitry Andric         return TC_Failed;
24810b57cec5SDimitry Andric       }
24825ffd83dbSDimitry Andric     }
24830b57cec5SDimitry Andric     Kind = CK_PointerToIntegral;
24840b57cec5SDimitry Andric     return TC_Success;
24850b57cec5SDimitry Andric   }
24860b57cec5SDimitry Andric 
24870b57cec5SDimitry Andric   if (SrcType->isIntegralOrEnumerationType()) {
24880b57cec5SDimitry Andric     assert(destIsPtr && "One type must be a pointer");
24895ffd83dbSDimitry Andric     checkIntToPointerCast(CStyle, OpRange, SrcExpr.get(), DestType, Self);
24900b57cec5SDimitry Andric     // C++ 5.2.10p5: A value of integral or enumeration type can be explicitly
24910b57cec5SDimitry Andric     //   converted to a pointer.
24920b57cec5SDimitry Andric     // C++ 5.2.10p9: [Note: ...a null pointer constant of integral type is not
24930b57cec5SDimitry Andric     //   necessarily converted to a null pointer value.]
24940b57cec5SDimitry Andric     Kind = CK_IntegralToPointer;
24950b57cec5SDimitry Andric     return TC_Success;
24960b57cec5SDimitry Andric   }
24970b57cec5SDimitry Andric 
24980b57cec5SDimitry Andric   if (!destIsPtr || !srcIsPtr) {
24990b57cec5SDimitry Andric     // With the valid non-pointer conversions out of the way, we can be even
25000b57cec5SDimitry Andric     // more stringent.
25010b57cec5SDimitry Andric     return TC_NotApplicable;
25020b57cec5SDimitry Andric   }
25030b57cec5SDimitry Andric 
25040b57cec5SDimitry Andric   // Cannot convert between block pointers and Objective-C object pointers.
25050b57cec5SDimitry Andric   if ((SrcType->isBlockPointerType() && DestType->isObjCObjectPointerType()) ||
25060b57cec5SDimitry Andric       (DestType->isBlockPointerType() && SrcType->isObjCObjectPointerType()))
25070b57cec5SDimitry Andric     return TC_NotApplicable;
25080b57cec5SDimitry Andric 
25090b57cec5SDimitry Andric   // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away constness.
25100b57cec5SDimitry Andric   // The C-style cast operator can.
25110b57cec5SDimitry Andric   TryCastResult SuccessResult = TC_Success;
25120b57cec5SDimitry Andric   if (auto CACK =
25130b57cec5SDimitry Andric           CastsAwayConstness(Self, SrcType, DestType, /*CheckCVR=*/!CStyle,
25140b57cec5SDimitry Andric                              /*CheckObjCLifetime=*/CStyle))
25150b57cec5SDimitry Andric     SuccessResult = getCastAwayConstnessCastKind(CACK, msg);
25160b57cec5SDimitry Andric 
25170b57cec5SDimitry Andric   if (IsAddressSpaceConversion(SrcType, DestType)) {
25180b57cec5SDimitry Andric     Kind = CK_AddressSpaceConversion;
25190b57cec5SDimitry Andric     assert(SrcType->isPointerType() && DestType->isPointerType());
25200b57cec5SDimitry Andric     if (!CStyle &&
25210b57cec5SDimitry Andric         !DestType->getPointeeType().getQualifiers().isAddressSpaceSupersetOf(
25220b57cec5SDimitry Andric             SrcType->getPointeeType().getQualifiers())) {
25230b57cec5SDimitry Andric       SuccessResult = TC_Failed;
25240b57cec5SDimitry Andric     }
25250b57cec5SDimitry Andric   } else if (IsLValueCast) {
25260b57cec5SDimitry Andric     Kind = CK_LValueBitCast;
25270b57cec5SDimitry Andric   } else if (DestType->isObjCObjectPointerType()) {
2528*0fca6ea1SDimitry Andric     Kind = Self.ObjC().PrepareCastToObjCObjectPointer(SrcExpr);
25290b57cec5SDimitry Andric   } else if (DestType->isBlockPointerType()) {
25300b57cec5SDimitry Andric     if (!SrcType->isBlockPointerType()) {
25310b57cec5SDimitry Andric       Kind = CK_AnyPointerToBlockPointerCast;
25320b57cec5SDimitry Andric     } else {
25330b57cec5SDimitry Andric       Kind = CK_BitCast;
25340b57cec5SDimitry Andric     }
25350b57cec5SDimitry Andric   } else {
25360b57cec5SDimitry Andric     Kind = CK_BitCast;
25370b57cec5SDimitry Andric   }
25380b57cec5SDimitry Andric 
25390b57cec5SDimitry Andric   // Any pointer can be cast to an Objective-C pointer type with a C-style
25400b57cec5SDimitry Andric   // cast.
25410b57cec5SDimitry Andric   if (CStyle && DestType->isObjCObjectPointerType()) {
25420b57cec5SDimitry Andric     return SuccessResult;
25430b57cec5SDimitry Andric   }
25440b57cec5SDimitry Andric   if (CStyle)
25450b57cec5SDimitry Andric     DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType);
25460b57cec5SDimitry Andric 
25470b57cec5SDimitry Andric   DiagnoseCallingConvCast(Self, SrcExpr, DestType, OpRange);
25480b57cec5SDimitry Andric 
25490b57cec5SDimitry Andric   // Not casting away constness, so the only remaining check is for compatible
25500b57cec5SDimitry Andric   // pointer categories.
25510b57cec5SDimitry Andric 
25520b57cec5SDimitry Andric   if (SrcType->isFunctionPointerType()) {
25530b57cec5SDimitry Andric     if (DestType->isFunctionPointerType()) {
25540b57cec5SDimitry Andric       // C++ 5.2.10p6: A pointer to a function can be explicitly converted to
25550b57cec5SDimitry Andric       // a pointer to a function of a different type.
25560b57cec5SDimitry Andric       return SuccessResult;
25570b57cec5SDimitry Andric     }
25580b57cec5SDimitry Andric 
25590b57cec5SDimitry Andric     // C++0x 5.2.10p8: Converting a pointer to a function into a pointer to
25600b57cec5SDimitry Andric     //   an object type or vice versa is conditionally-supported.
25610b57cec5SDimitry Andric     // Compilers support it in C++03 too, though, because it's necessary for
25620b57cec5SDimitry Andric     // casting the return value of dlsym() and GetProcAddress().
25630b57cec5SDimitry Andric     // FIXME: Conditionally-supported behavior should be configurable in the
25640b57cec5SDimitry Andric     // TargetInfo or similar.
25650b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(),
25660b57cec5SDimitry Andric               Self.getLangOpts().CPlusPlus11 ?
25670b57cec5SDimitry Andric                 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
25680b57cec5SDimitry Andric       << OpRange;
25690b57cec5SDimitry Andric     return SuccessResult;
25700b57cec5SDimitry Andric   }
25710b57cec5SDimitry Andric 
25720b57cec5SDimitry Andric   if (DestType->isFunctionPointerType()) {
25730b57cec5SDimitry Andric     // See above.
25740b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(),
25750b57cec5SDimitry Andric               Self.getLangOpts().CPlusPlus11 ?
25760b57cec5SDimitry Andric                 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
25770b57cec5SDimitry Andric       << OpRange;
25780b57cec5SDimitry Andric     return SuccessResult;
25790b57cec5SDimitry Andric   }
25800b57cec5SDimitry Andric 
258113138422SDimitry Andric   // Diagnose address space conversion in nested pointers.
258213138422SDimitry Andric   QualType DestPtee = DestType->getPointeeType().isNull()
258313138422SDimitry Andric                           ? DestType->getPointeeType()
258413138422SDimitry Andric                           : DestType->getPointeeType()->getPointeeType();
258513138422SDimitry Andric   QualType SrcPtee = SrcType->getPointeeType().isNull()
258613138422SDimitry Andric                          ? SrcType->getPointeeType()
258713138422SDimitry Andric                          : SrcType->getPointeeType()->getPointeeType();
258813138422SDimitry Andric   while (!DestPtee.isNull() && !SrcPtee.isNull()) {
258913138422SDimitry Andric     if (DestPtee.getAddressSpace() != SrcPtee.getAddressSpace()) {
259013138422SDimitry Andric       Self.Diag(OpRange.getBegin(),
259113138422SDimitry Andric                 diag::warn_bad_cxx_cast_nested_pointer_addr_space)
259213138422SDimitry Andric           << CStyle << SrcType << DestType << SrcExpr.get()->getSourceRange();
259313138422SDimitry Andric       break;
259413138422SDimitry Andric     }
259513138422SDimitry Andric     DestPtee = DestPtee->getPointeeType();
259613138422SDimitry Andric     SrcPtee = SrcPtee->getPointeeType();
259713138422SDimitry Andric   }
259813138422SDimitry Andric 
25990b57cec5SDimitry Andric   // C++ 5.2.10p7: A pointer to an object can be explicitly converted to
26000b57cec5SDimitry Andric   //   a pointer to an object of different type.
26010b57cec5SDimitry Andric   // Void pointers are not specified, but supported by every compiler out there.
26020b57cec5SDimitry Andric   // So we finish by allowing everything that remains - it's got to be two
26030b57cec5SDimitry Andric   // object pointers.
26040b57cec5SDimitry Andric   return SuccessResult;
26050b57cec5SDimitry Andric }
26060b57cec5SDimitry Andric 
26070b57cec5SDimitry Andric static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr,
26080b57cec5SDimitry Andric                                          QualType DestType, bool CStyle,
26095ffd83dbSDimitry Andric                                          unsigned &msg, CastKind &Kind) {
261081ad6265SDimitry Andric   if (!Self.getLangOpts().OpenCL && !Self.getLangOpts().SYCLIsDevice)
26110b57cec5SDimitry Andric     // FIXME: As compiler doesn't have any information about overlapping addr
26120b57cec5SDimitry Andric     // spaces at the moment we have to be permissive here.
26130b57cec5SDimitry Andric     return TC_NotApplicable;
26140b57cec5SDimitry Andric   // Even though the logic below is general enough and can be applied to
26150b57cec5SDimitry Andric   // non-OpenCL mode too, we fast-path above because no other languages
26160b57cec5SDimitry Andric   // define overlapping address spaces currently.
26170b57cec5SDimitry Andric   auto SrcType = SrcExpr.get()->getType();
26185ffd83dbSDimitry Andric   // FIXME: Should this be generalized to references? The reference parameter
26195ffd83dbSDimitry Andric   // however becomes a reference pointee type here and therefore rejected.
26205ffd83dbSDimitry Andric   // Perhaps this is the right behavior though according to C++.
26210b57cec5SDimitry Andric   auto SrcPtrType = SrcType->getAs<PointerType>();
26220b57cec5SDimitry Andric   if (!SrcPtrType)
26230b57cec5SDimitry Andric     return TC_NotApplicable;
26240b57cec5SDimitry Andric   auto DestPtrType = DestType->getAs<PointerType>();
26250b57cec5SDimitry Andric   if (!DestPtrType)
26260b57cec5SDimitry Andric     return TC_NotApplicable;
26270b57cec5SDimitry Andric   auto SrcPointeeType = SrcPtrType->getPointeeType();
26280b57cec5SDimitry Andric   auto DestPointeeType = DestPtrType->getPointeeType();
26295ffd83dbSDimitry Andric   if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType)) {
26300b57cec5SDimitry Andric     msg = diag::err_bad_cxx_cast_addr_space_mismatch;
26310b57cec5SDimitry Andric     return TC_Failed;
26320b57cec5SDimitry Andric   }
26330b57cec5SDimitry Andric   auto SrcPointeeTypeWithoutAS =
26340b57cec5SDimitry Andric       Self.Context.removeAddrSpaceQualType(SrcPointeeType.getCanonicalType());
26350b57cec5SDimitry Andric   auto DestPointeeTypeWithoutAS =
26360b57cec5SDimitry Andric       Self.Context.removeAddrSpaceQualType(DestPointeeType.getCanonicalType());
26375ffd83dbSDimitry Andric   if (Self.Context.hasSameType(SrcPointeeTypeWithoutAS,
26385ffd83dbSDimitry Andric                                DestPointeeTypeWithoutAS)) {
26395ffd83dbSDimitry Andric     Kind = SrcPointeeType.getAddressSpace() == DestPointeeType.getAddressSpace()
26405ffd83dbSDimitry Andric                ? CK_NoOp
26415ffd83dbSDimitry Andric                : CK_AddressSpaceConversion;
26425ffd83dbSDimitry Andric     return TC_Success;
26435ffd83dbSDimitry Andric   } else {
26445ffd83dbSDimitry Andric     return TC_NotApplicable;
26455ffd83dbSDimitry Andric   }
26460b57cec5SDimitry Andric }
26470b57cec5SDimitry Andric 
26480b57cec5SDimitry Andric void CastOperation::checkAddressSpaceCast(QualType SrcType, QualType DestType) {
26490b57cec5SDimitry Andric   // In OpenCL only conversions between pointers to objects in overlapping
26500b57cec5SDimitry Andric   // addr spaces are allowed. v2.0 s6.5.5 - Generic addr space overlaps
26510b57cec5SDimitry Andric   // with any named one, except for constant.
26520b57cec5SDimitry Andric 
26530b57cec5SDimitry Andric   // Converting the top level pointee addrspace is permitted for compatible
26540b57cec5SDimitry Andric   // addrspaces (such as 'generic int *' to 'local int *' or vice versa), but
26550b57cec5SDimitry Andric   // if any of the nested pointee addrspaces differ, we emit a warning
26560b57cec5SDimitry Andric   // regardless of addrspace compatibility. This makes
26570b57cec5SDimitry Andric   //   local int ** p;
26580b57cec5SDimitry Andric   //   return (generic int **) p;
26590b57cec5SDimitry Andric   // warn even though local -> generic is permitted.
26600b57cec5SDimitry Andric   if (Self.getLangOpts().OpenCL) {
26610b57cec5SDimitry Andric     const Type *DestPtr, *SrcPtr;
26620b57cec5SDimitry Andric     bool Nested = false;
26630b57cec5SDimitry Andric     unsigned DiagID = diag::err_typecheck_incompatible_address_space;
26640b57cec5SDimitry Andric     DestPtr = Self.getASTContext().getCanonicalType(DestType.getTypePtr()),
26650b57cec5SDimitry Andric     SrcPtr  = Self.getASTContext().getCanonicalType(SrcType.getTypePtr());
26660b57cec5SDimitry Andric 
26670b57cec5SDimitry Andric     while (isa<PointerType>(DestPtr) && isa<PointerType>(SrcPtr)) {
26680b57cec5SDimitry Andric       const PointerType *DestPPtr = cast<PointerType>(DestPtr);
26690b57cec5SDimitry Andric       const PointerType *SrcPPtr = cast<PointerType>(SrcPtr);
26700b57cec5SDimitry Andric       QualType DestPPointee = DestPPtr->getPointeeType();
26710b57cec5SDimitry Andric       QualType SrcPPointee = SrcPPtr->getPointeeType();
26725ffd83dbSDimitry Andric       if (Nested
26735ffd83dbSDimitry Andric               ? DestPPointee.getAddressSpace() != SrcPPointee.getAddressSpace()
26745ffd83dbSDimitry Andric               : !DestPPointee.isAddressSpaceOverlapping(SrcPPointee)) {
26750b57cec5SDimitry Andric         Self.Diag(OpRange.getBegin(), DiagID)
26760b57cec5SDimitry Andric             << SrcType << DestType << Sema::AA_Casting
26770b57cec5SDimitry Andric             << SrcExpr.get()->getSourceRange();
26780b57cec5SDimitry Andric         if (!Nested)
26790b57cec5SDimitry Andric           SrcExpr = ExprError();
26800b57cec5SDimitry Andric         return;
26810b57cec5SDimitry Andric       }
26820b57cec5SDimitry Andric 
26830b57cec5SDimitry Andric       DestPtr = DestPPtr->getPointeeType().getTypePtr();
26840b57cec5SDimitry Andric       SrcPtr = SrcPPtr->getPointeeType().getTypePtr();
26850b57cec5SDimitry Andric       Nested = true;
26860b57cec5SDimitry Andric       DiagID = diag::ext_nested_pointer_qualifier_mismatch;
26870b57cec5SDimitry Andric     }
26880b57cec5SDimitry Andric   }
26890b57cec5SDimitry Andric }
26900b57cec5SDimitry Andric 
2691fe6060f1SDimitry Andric bool Sema::ShouldSplatAltivecScalarInCast(const VectorType *VecTy) {
2692fe6060f1SDimitry Andric   bool SrcCompatXL = this->getLangOpts().getAltivecSrcCompat() ==
2693fe6060f1SDimitry Andric                      LangOptions::AltivecSrcCompatKind::XL;
26945f757f3fSDimitry Andric   VectorKind VKind = VecTy->getVectorKind();
2695fe6060f1SDimitry Andric 
26965f757f3fSDimitry Andric   if ((VKind == VectorKind::AltiVecVector) ||
26975f757f3fSDimitry Andric       (SrcCompatXL && ((VKind == VectorKind::AltiVecBool) ||
26985f757f3fSDimitry Andric                        (VKind == VectorKind::AltiVecPixel)))) {
2699fe6060f1SDimitry Andric     return true;
2700fe6060f1SDimitry Andric   }
2701fe6060f1SDimitry Andric   return false;
2702fe6060f1SDimitry Andric }
2703fe6060f1SDimitry Andric 
2704349cc55cSDimitry Andric bool Sema::CheckAltivecInitFromScalar(SourceRange R, QualType VecTy,
2705349cc55cSDimitry Andric                                       QualType SrcTy) {
2706349cc55cSDimitry Andric   bool SrcCompatGCC = this->getLangOpts().getAltivecSrcCompat() ==
2707349cc55cSDimitry Andric                       LangOptions::AltivecSrcCompatKind::GCC;
2708349cc55cSDimitry Andric   if (this->getLangOpts().AltiVec && SrcCompatGCC) {
2709349cc55cSDimitry Andric     this->Diag(R.getBegin(),
2710349cc55cSDimitry Andric                diag::err_invalid_conversion_between_vector_and_integer)
2711349cc55cSDimitry Andric         << VecTy << SrcTy << R;
2712349cc55cSDimitry Andric     return true;
2713349cc55cSDimitry Andric   }
2714349cc55cSDimitry Andric   return false;
2715349cc55cSDimitry Andric }
2716349cc55cSDimitry Andric 
27170b57cec5SDimitry Andric void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
27180b57cec5SDimitry Andric                                        bool ListInitialization) {
27190b57cec5SDimitry Andric   assert(Self.getLangOpts().CPlusPlus);
27200b57cec5SDimitry Andric 
27210b57cec5SDimitry Andric   // Handle placeholders.
27220b57cec5SDimitry Andric   if (isPlaceholder()) {
27230b57cec5SDimitry Andric     // C-style casts can resolve __unknown_any types.
27240b57cec5SDimitry Andric     if (claimPlaceholder(BuiltinType::UnknownAny)) {
27250b57cec5SDimitry Andric       SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,
27260b57cec5SDimitry Andric                                          SrcExpr.get(), Kind,
27270b57cec5SDimitry Andric                                          ValueKind, BasePath);
27280b57cec5SDimitry Andric       return;
27290b57cec5SDimitry Andric     }
27300b57cec5SDimitry Andric 
27310b57cec5SDimitry Andric     checkNonOverloadPlaceholders();
27320b57cec5SDimitry Andric     if (SrcExpr.isInvalid())
27330b57cec5SDimitry Andric       return;
27340b57cec5SDimitry Andric   }
27350b57cec5SDimitry Andric 
27360b57cec5SDimitry Andric   // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
27370b57cec5SDimitry Andric   // This test is outside everything else because it's the only case where
27380b57cec5SDimitry Andric   // a non-lvalue-reference target type does not lead to decay.
27390b57cec5SDimitry Andric   if (DestType->isVoidType()) {
27400b57cec5SDimitry Andric     Kind = CK_ToVoid;
27410b57cec5SDimitry Andric 
27420b57cec5SDimitry Andric     if (claimPlaceholder(BuiltinType::Overload)) {
27430b57cec5SDimitry Andric       Self.ResolveAndFixSingleFunctionTemplateSpecialization(
27440b57cec5SDimitry Andric                   SrcExpr, /* Decay Function to ptr */ false,
27450b57cec5SDimitry Andric                   /* Complain */ true, DestRange, DestType,
27460b57cec5SDimitry Andric                   diag::err_bad_cstyle_cast_overload);
27470b57cec5SDimitry Andric       if (SrcExpr.isInvalid())
27480b57cec5SDimitry Andric         return;
27490b57cec5SDimitry Andric     }
27500b57cec5SDimitry Andric 
27510b57cec5SDimitry Andric     SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
27520b57cec5SDimitry Andric     return;
27530b57cec5SDimitry Andric   }
27540b57cec5SDimitry Andric 
27550b57cec5SDimitry Andric   // If the type is dependent, we won't do any other semantic analysis now.
27560b57cec5SDimitry Andric   if (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() ||
27570b57cec5SDimitry Andric       SrcExpr.get()->isValueDependent()) {
27580b57cec5SDimitry Andric     assert(Kind == CK_Dependent);
27590b57cec5SDimitry Andric     return;
27600b57cec5SDimitry Andric   }
27610b57cec5SDimitry Andric 
2762fe6060f1SDimitry Andric   if (ValueKind == VK_PRValue && !DestType->isRecordType() &&
27630b57cec5SDimitry Andric       !isPlaceholder(BuiltinType::Overload)) {
27640b57cec5SDimitry Andric     SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
27650b57cec5SDimitry Andric     if (SrcExpr.isInvalid())
27660b57cec5SDimitry Andric       return;
27670b57cec5SDimitry Andric   }
27680b57cec5SDimitry Andric 
27690b57cec5SDimitry Andric   // AltiVec vector initialization with a single literal.
2770349cc55cSDimitry Andric   if (const VectorType *vecTy = DestType->getAs<VectorType>()) {
2771349cc55cSDimitry Andric     if (Self.CheckAltivecInitFromScalar(OpRange, DestType,
2772349cc55cSDimitry Andric                                         SrcExpr.get()->getType())) {
2773349cc55cSDimitry Andric       SrcExpr = ExprError();
2774349cc55cSDimitry Andric       return;
2775349cc55cSDimitry Andric     }
2776fe6060f1SDimitry Andric     if (Self.ShouldSplatAltivecScalarInCast(vecTy) &&
2777fe6060f1SDimitry Andric         (SrcExpr.get()->getType()->isIntegerType() ||
2778fe6060f1SDimitry Andric          SrcExpr.get()->getType()->isFloatingType())) {
27790b57cec5SDimitry Andric       Kind = CK_VectorSplat;
27800b57cec5SDimitry Andric       SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());
27810b57cec5SDimitry Andric       return;
27820b57cec5SDimitry Andric     }
2783349cc55cSDimitry Andric   }
27840b57cec5SDimitry Andric 
278506c3fb27SDimitry Andric   // WebAssembly tables cannot be cast.
278606c3fb27SDimitry Andric   QualType SrcType = SrcExpr.get()->getType();
278706c3fb27SDimitry Andric   if (SrcType->isWebAssemblyTableType()) {
278806c3fb27SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
278906c3fb27SDimitry Andric         << 1 << SrcExpr.get()->getSourceRange();
279006c3fb27SDimitry Andric     SrcExpr = ExprError();
279106c3fb27SDimitry Andric     return;
279206c3fb27SDimitry Andric   }
279306c3fb27SDimitry Andric 
27940b57cec5SDimitry Andric   // C++ [expr.cast]p5: The conversions performed by
27950b57cec5SDimitry Andric   //   - a const_cast,
27960b57cec5SDimitry Andric   //   - a static_cast,
27970b57cec5SDimitry Andric   //   - a static_cast followed by a const_cast,
27980b57cec5SDimitry Andric   //   - a reinterpret_cast, or
27990b57cec5SDimitry Andric   //   - a reinterpret_cast followed by a const_cast,
28000b57cec5SDimitry Andric   //   can be performed using the cast notation of explicit type conversion.
28010b57cec5SDimitry Andric   //   [...] If a conversion can be interpreted in more than one of the ways
28020b57cec5SDimitry Andric   //   listed above, the interpretation that appears first in the list is used,
28030b57cec5SDimitry Andric   //   even if a cast resulting from that interpretation is ill-formed.
28040b57cec5SDimitry Andric   // In plain language, this means trying a const_cast ...
28050b57cec5SDimitry Andric   // Note that for address space we check compatibility after const_cast.
28060b57cec5SDimitry Andric   unsigned msg = diag::err_bad_cxx_cast_generic;
28070b57cec5SDimitry Andric   TryCastResult tcr = TryConstCast(Self, SrcExpr, DestType,
28080b57cec5SDimitry Andric                                    /*CStyle*/ true, msg);
28090b57cec5SDimitry Andric   if (SrcExpr.isInvalid())
28100b57cec5SDimitry Andric     return;
28110b57cec5SDimitry Andric   if (isValidCast(tcr))
28120b57cec5SDimitry Andric     Kind = CK_NoOp;
28130b57cec5SDimitry Andric 
2814*0fca6ea1SDimitry Andric   CheckedConversionKind CCK = FunctionalStyle
2815*0fca6ea1SDimitry Andric                                   ? CheckedConversionKind::FunctionalCast
2816*0fca6ea1SDimitry Andric                                   : CheckedConversionKind::CStyleCast;
28170b57cec5SDimitry Andric   if (tcr == TC_NotApplicable) {
28185ffd83dbSDimitry Andric     tcr = TryAddressSpaceCast(Self, SrcExpr, DestType, /*CStyle*/ true, msg,
28195ffd83dbSDimitry Andric                               Kind);
28200b57cec5SDimitry Andric     if (SrcExpr.isInvalid())
28210b57cec5SDimitry Andric       return;
28220b57cec5SDimitry Andric 
28230b57cec5SDimitry Andric     if (tcr == TC_NotApplicable) {
28245ffd83dbSDimitry Andric       // ... or if that is not possible, a static_cast, ignoring const and
28255ffd83dbSDimitry Andric       // addr space, ...
28260b57cec5SDimitry Andric       tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange, msg, Kind,
28270b57cec5SDimitry Andric                           BasePath, ListInitialization);
28280b57cec5SDimitry Andric       if (SrcExpr.isInvalid())
28290b57cec5SDimitry Andric         return;
28300b57cec5SDimitry Andric 
28310b57cec5SDimitry Andric       if (tcr == TC_NotApplicable) {
28325ffd83dbSDimitry Andric         // ... and finally a reinterpret_cast, ignoring const and addr space.
28330b57cec5SDimitry Andric         tcr = TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/ true,
28340b57cec5SDimitry Andric                                  OpRange, msg, Kind);
28350b57cec5SDimitry Andric         if (SrcExpr.isInvalid())
28360b57cec5SDimitry Andric           return;
28370b57cec5SDimitry Andric       }
28380b57cec5SDimitry Andric     }
28390b57cec5SDimitry Andric   }
28400b57cec5SDimitry Andric 
28410b57cec5SDimitry Andric   if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
28420b57cec5SDimitry Andric       isValidCast(tcr))
28430b57cec5SDimitry Andric     checkObjCConversion(CCK);
28440b57cec5SDimitry Andric 
28450b57cec5SDimitry Andric   if (tcr != TC_Success && msg != 0) {
28460b57cec5SDimitry Andric     if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
28470b57cec5SDimitry Andric       DeclAccessPair Found;
28480b57cec5SDimitry Andric       FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),
28490b57cec5SDimitry Andric                                 DestType,
28500b57cec5SDimitry Andric                                 /*Complain*/ true,
28510b57cec5SDimitry Andric                                 Found);
28520b57cec5SDimitry Andric       if (Fn) {
28530b57cec5SDimitry Andric         // If DestType is a function type (not to be confused with the function
28540b57cec5SDimitry Andric         // pointer type), it will be possible to resolve the function address,
28550b57cec5SDimitry Andric         // but the type cast should be considered as failure.
28560b57cec5SDimitry Andric         OverloadExpr *OE = OverloadExpr::find(SrcExpr.get()).Expression;
28570b57cec5SDimitry Andric         Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload)
28580b57cec5SDimitry Andric           << OE->getName() << DestType << OpRange
28590b57cec5SDimitry Andric           << OE->getQualifierLoc().getSourceRange();
28600b57cec5SDimitry Andric         Self.NoteAllOverloadCandidates(SrcExpr.get());
28610b57cec5SDimitry Andric       }
28620b57cec5SDimitry Andric     } else {
28630b57cec5SDimitry Andric       diagnoseBadCast(Self, msg, (FunctionalStyle ? CT_Functional : CT_CStyle),
28640b57cec5SDimitry Andric                       OpRange, SrcExpr.get(), DestType, ListInitialization);
28650b57cec5SDimitry Andric     }
28660b57cec5SDimitry Andric   }
28670b57cec5SDimitry Andric 
28680b57cec5SDimitry Andric   if (isValidCast(tcr)) {
28690b57cec5SDimitry Andric     if (Kind == CK_BitCast)
28700b57cec5SDimitry Andric       checkCastAlign();
2871fe6060f1SDimitry Andric 
2872bdd1243dSDimitry Andric     if (unsigned DiagID = checkCastFunctionType(Self, SrcExpr, DestType))
2873bdd1243dSDimitry Andric       Self.Diag(OpRange.getBegin(), DiagID)
2874fe6060f1SDimitry Andric           << SrcExpr.get()->getType() << DestType << OpRange;
2875fe6060f1SDimitry Andric 
28760b57cec5SDimitry Andric   } else {
28770b57cec5SDimitry Andric     SrcExpr = ExprError();
28780b57cec5SDimitry Andric   }
28790b57cec5SDimitry Andric }
28800b57cec5SDimitry Andric 
28810b57cec5SDimitry Andric /// DiagnoseBadFunctionCast - Warn whenever a function call is cast to a
28820b57cec5SDimitry Andric ///  non-matching type. Such as enum function call to int, int call to
28830b57cec5SDimitry Andric /// pointer; etc. Cast to 'void' is an exception.
28840b57cec5SDimitry Andric static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr,
28850b57cec5SDimitry Andric                                   QualType DestType) {
28860b57cec5SDimitry Andric   if (Self.Diags.isIgnored(diag::warn_bad_function_cast,
28870b57cec5SDimitry Andric                            SrcExpr.get()->getExprLoc()))
28880b57cec5SDimitry Andric     return;
28890b57cec5SDimitry Andric 
28900b57cec5SDimitry Andric   if (!isa<CallExpr>(SrcExpr.get()))
28910b57cec5SDimitry Andric     return;
28920b57cec5SDimitry Andric 
28930b57cec5SDimitry Andric   QualType SrcType = SrcExpr.get()->getType();
28940b57cec5SDimitry Andric   if (DestType.getUnqualifiedType()->isVoidType())
28950b57cec5SDimitry Andric     return;
28960b57cec5SDimitry Andric   if ((SrcType->isAnyPointerType() || SrcType->isBlockPointerType())
28970b57cec5SDimitry Andric       && (DestType->isAnyPointerType() || DestType->isBlockPointerType()))
28980b57cec5SDimitry Andric     return;
28990b57cec5SDimitry Andric   if (SrcType->isIntegerType() && DestType->isIntegerType() &&
29000b57cec5SDimitry Andric       (SrcType->isBooleanType() == DestType->isBooleanType()) &&
29010b57cec5SDimitry Andric       (SrcType->isEnumeralType() == DestType->isEnumeralType()))
29020b57cec5SDimitry Andric     return;
29030b57cec5SDimitry Andric   if (SrcType->isRealFloatingType() && DestType->isRealFloatingType())
29040b57cec5SDimitry Andric     return;
29050b57cec5SDimitry Andric   if (SrcType->isEnumeralType() && DestType->isEnumeralType())
29060b57cec5SDimitry Andric     return;
29070b57cec5SDimitry Andric   if (SrcType->isComplexType() && DestType->isComplexType())
29080b57cec5SDimitry Andric     return;
29090b57cec5SDimitry Andric   if (SrcType->isComplexIntegerType() && DestType->isComplexIntegerType())
29100b57cec5SDimitry Andric     return;
2911e8d8bef9SDimitry Andric   if (SrcType->isFixedPointType() && DestType->isFixedPointType())
2912e8d8bef9SDimitry Andric     return;
29130b57cec5SDimitry Andric 
29140b57cec5SDimitry Andric   Self.Diag(SrcExpr.get()->getExprLoc(),
29150b57cec5SDimitry Andric             diag::warn_bad_function_cast)
29160b57cec5SDimitry Andric             << SrcType << DestType << SrcExpr.get()->getSourceRange();
29170b57cec5SDimitry Andric }
29180b57cec5SDimitry Andric 
29190b57cec5SDimitry Andric /// Check the semantics of a C-style cast operation, in C.
29200b57cec5SDimitry Andric void CastOperation::CheckCStyleCast() {
29210b57cec5SDimitry Andric   assert(!Self.getLangOpts().CPlusPlus);
29220b57cec5SDimitry Andric 
29230b57cec5SDimitry Andric   // C-style casts can resolve __unknown_any types.
29240b57cec5SDimitry Andric   if (claimPlaceholder(BuiltinType::UnknownAny)) {
29250b57cec5SDimitry Andric     SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,
29260b57cec5SDimitry Andric                                        SrcExpr.get(), Kind,
29270b57cec5SDimitry Andric                                        ValueKind, BasePath);
29280b57cec5SDimitry Andric     return;
29290b57cec5SDimitry Andric   }
29300b57cec5SDimitry Andric 
29310b57cec5SDimitry Andric   // C99 6.5.4p2: the cast type needs to be void or scalar and the expression
29320b57cec5SDimitry Andric   // type needs to be scalar.
29330b57cec5SDimitry Andric   if (DestType->isVoidType()) {
29340b57cec5SDimitry Andric     // We don't necessarily do lvalue-to-rvalue conversions on this.
29350b57cec5SDimitry Andric     SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
29360b57cec5SDimitry Andric     if (SrcExpr.isInvalid())
29370b57cec5SDimitry Andric       return;
29380b57cec5SDimitry Andric 
29390b57cec5SDimitry Andric     // Cast to void allows any expr type.
29400b57cec5SDimitry Andric     Kind = CK_ToVoid;
29410b57cec5SDimitry Andric     return;
29420b57cec5SDimitry Andric   }
29430b57cec5SDimitry Andric 
2944e8d8bef9SDimitry Andric   // If the type is dependent, we won't do any other semantic analysis now.
2945e8d8bef9SDimitry Andric   if (Self.getASTContext().isDependenceAllowed() &&
2946e8d8bef9SDimitry Andric       (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() ||
2947e8d8bef9SDimitry Andric        SrcExpr.get()->isValueDependent())) {
2948e8d8bef9SDimitry Andric     assert((DestType->containsErrors() || SrcExpr.get()->containsErrors() ||
2949e8d8bef9SDimitry Andric             SrcExpr.get()->containsErrors()) &&
2950e8d8bef9SDimitry Andric            "should only occur in error-recovery path.");
2951e8d8bef9SDimitry Andric     assert(Kind == CK_Dependent);
2952e8d8bef9SDimitry Andric     return;
2953e8d8bef9SDimitry Andric   }
2954e8d8bef9SDimitry Andric 
29550b57cec5SDimitry Andric   // Overloads are allowed with C extensions, so we need to support them.
29560b57cec5SDimitry Andric   if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
29570b57cec5SDimitry Andric     DeclAccessPair DAP;
29580b57cec5SDimitry Andric     if (FunctionDecl *FD = Self.ResolveAddressOfOverloadedFunction(
29590b57cec5SDimitry Andric             SrcExpr.get(), DestType, /*Complain=*/true, DAP))
29600b57cec5SDimitry Andric       SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr.get(), DAP, FD);
29610b57cec5SDimitry Andric     else
29620b57cec5SDimitry Andric       return;
29630b57cec5SDimitry Andric     assert(SrcExpr.isUsable());
29640b57cec5SDimitry Andric   }
29650b57cec5SDimitry Andric   SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
29660b57cec5SDimitry Andric   if (SrcExpr.isInvalid())
29670b57cec5SDimitry Andric     return;
29680b57cec5SDimitry Andric   QualType SrcType = SrcExpr.get()->getType();
29690b57cec5SDimitry Andric 
297006c3fb27SDimitry Andric   if (SrcType->isWebAssemblyTableType()) {
297106c3fb27SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)
297206c3fb27SDimitry Andric         << 1 << SrcExpr.get()->getSourceRange();
297306c3fb27SDimitry Andric     SrcExpr = ExprError();
297406c3fb27SDimitry Andric     return;
297506c3fb27SDimitry Andric   }
297606c3fb27SDimitry Andric 
29770b57cec5SDimitry Andric   assert(!SrcType->isPlaceholderType());
29780b57cec5SDimitry Andric 
29790b57cec5SDimitry Andric   checkAddressSpaceCast(SrcType, DestType);
29800b57cec5SDimitry Andric   if (SrcExpr.isInvalid())
29810b57cec5SDimitry Andric     return;
29820b57cec5SDimitry Andric 
29830b57cec5SDimitry Andric   if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
29840b57cec5SDimitry Andric                                diag::err_typecheck_cast_to_incomplete)) {
29850b57cec5SDimitry Andric     SrcExpr = ExprError();
29860b57cec5SDimitry Andric     return;
29870b57cec5SDimitry Andric   }
29880b57cec5SDimitry Andric 
29895ffd83dbSDimitry Andric   // Allow casting a sizeless built-in type to itself.
29905ffd83dbSDimitry Andric   if (DestType->isSizelessBuiltinType() &&
29915ffd83dbSDimitry Andric       Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {
29925ffd83dbSDimitry Andric     Kind = CK_NoOp;
29935ffd83dbSDimitry Andric     return;
29945ffd83dbSDimitry Andric   }
29955ffd83dbSDimitry Andric 
2996e8d8bef9SDimitry Andric   // Allow bitcasting between compatible SVE vector types.
2997e8d8bef9SDimitry Andric   if ((SrcType->isVectorType() || DestType->isVectorType()) &&
2998e8d8bef9SDimitry Andric       Self.isValidSveBitcast(SrcType, DestType)) {
2999e8d8bef9SDimitry Andric     Kind = CK_BitCast;
3000e8d8bef9SDimitry Andric     return;
3001e8d8bef9SDimitry Andric   }
3002e8d8bef9SDimitry Andric 
300306c3fb27SDimitry Andric   // Allow bitcasting between compatible RVV vector types.
300406c3fb27SDimitry Andric   if ((SrcType->isVectorType() || DestType->isVectorType()) &&
3005*0fca6ea1SDimitry Andric       Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {
300606c3fb27SDimitry Andric     Kind = CK_BitCast;
300706c3fb27SDimitry Andric     return;
300806c3fb27SDimitry Andric   }
300906c3fb27SDimitry Andric 
3010fe6060f1SDimitry Andric   if (!DestType->isScalarType() && !DestType->isVectorType() &&
3011fe6060f1SDimitry Andric       !DestType->isMatrixType()) {
30120b57cec5SDimitry Andric     const RecordType *DestRecordTy = DestType->getAs<RecordType>();
30130b57cec5SDimitry Andric 
30140b57cec5SDimitry Andric     if (DestRecordTy && Self.Context.hasSameUnqualifiedType(DestType, SrcType)){
30150b57cec5SDimitry Andric       // GCC struct/union extension: allow cast to self.
30160b57cec5SDimitry Andric       Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)
30170b57cec5SDimitry Andric         << DestType << SrcExpr.get()->getSourceRange();
30180b57cec5SDimitry Andric       Kind = CK_NoOp;
30190b57cec5SDimitry Andric       return;
30200b57cec5SDimitry Andric     }
30210b57cec5SDimitry Andric 
30220b57cec5SDimitry Andric     // GCC's cast to union extension.
30230b57cec5SDimitry Andric     if (DestRecordTy && DestRecordTy->getDecl()->isUnion()) {
30240b57cec5SDimitry Andric       RecordDecl *RD = DestRecordTy->getDecl();
30250b57cec5SDimitry Andric       if (CastExpr::getTargetFieldForToUnionCast(RD, SrcType)) {
30260b57cec5SDimitry Andric         Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
30270b57cec5SDimitry Andric           << SrcExpr.get()->getSourceRange();
30280b57cec5SDimitry Andric         Kind = CK_ToUnion;
30290b57cec5SDimitry Andric         return;
30300b57cec5SDimitry Andric       } else {
30310b57cec5SDimitry Andric         Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
30320b57cec5SDimitry Andric           << SrcType << SrcExpr.get()->getSourceRange();
30330b57cec5SDimitry Andric         SrcExpr = ExprError();
30340b57cec5SDimitry Andric         return;
30350b57cec5SDimitry Andric       }
30360b57cec5SDimitry Andric     }
30370b57cec5SDimitry Andric 
30380b57cec5SDimitry Andric     // OpenCL v2.0 s6.13.10 - Allow casts from '0' to event_t type.
30390b57cec5SDimitry Andric     if (Self.getLangOpts().OpenCL && DestType->isEventT()) {
30400b57cec5SDimitry Andric       Expr::EvalResult Result;
30410b57cec5SDimitry Andric       if (SrcExpr.get()->EvaluateAsInt(Result, Self.Context)) {
30420b57cec5SDimitry Andric         llvm::APSInt CastInt = Result.Val.getInt();
30430b57cec5SDimitry Andric         if (0 == CastInt) {
30440b57cec5SDimitry Andric           Kind = CK_ZeroToOCLOpaqueType;
30450b57cec5SDimitry Andric           return;
30460b57cec5SDimitry Andric         }
30470b57cec5SDimitry Andric         Self.Diag(OpRange.getBegin(),
30480b57cec5SDimitry Andric                   diag::err_opencl_cast_non_zero_to_event_t)
3049fe6060f1SDimitry Andric                   << toString(CastInt, 10) << SrcExpr.get()->getSourceRange();
30500b57cec5SDimitry Andric         SrcExpr = ExprError();
30510b57cec5SDimitry Andric         return;
30520b57cec5SDimitry Andric       }
30530b57cec5SDimitry Andric     }
30540b57cec5SDimitry Andric 
30550b57cec5SDimitry Andric     // Reject any other conversions to non-scalar types.
30560b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar)
30570b57cec5SDimitry Andric       << DestType << SrcExpr.get()->getSourceRange();
30580b57cec5SDimitry Andric     SrcExpr = ExprError();
30590b57cec5SDimitry Andric     return;
30600b57cec5SDimitry Andric   }
30610b57cec5SDimitry Andric 
3062fe6060f1SDimitry Andric   // The type we're casting to is known to be a scalar, a vector, or a matrix.
30630b57cec5SDimitry Andric 
3064fe6060f1SDimitry Andric   // Require the operand to be a scalar, a vector, or a matrix.
3065fe6060f1SDimitry Andric   if (!SrcType->isScalarType() && !SrcType->isVectorType() &&
3066fe6060f1SDimitry Andric       !SrcType->isMatrixType()) {
30670b57cec5SDimitry Andric     Self.Diag(SrcExpr.get()->getExprLoc(),
30680b57cec5SDimitry Andric               diag::err_typecheck_expect_scalar_operand)
30690b57cec5SDimitry Andric       << SrcType << SrcExpr.get()->getSourceRange();
30700b57cec5SDimitry Andric     SrcExpr = ExprError();
30710b57cec5SDimitry Andric     return;
30720b57cec5SDimitry Andric   }
30730b57cec5SDimitry Andric 
30745f757f3fSDimitry Andric   // C23 6.5.4p4:
3075bdd1243dSDimitry Andric   //   The type nullptr_t shall not be converted to any type other than void,
3076bdd1243dSDimitry Andric   //   bool, or a pointer type. No type other than nullptr_t shall be converted
3077bdd1243dSDimitry Andric   //   to nullptr_t.
3078bdd1243dSDimitry Andric   if (SrcType->isNullPtrType()) {
3079bdd1243dSDimitry Andric     // FIXME: 6.3.2.4p2 says that nullptr_t can be converted to itself, but
3080bdd1243dSDimitry Andric     // 6.5.4p4 is a constraint check and nullptr_t is not void, bool, or a
3081bdd1243dSDimitry Andric     // pointer type. We're not going to diagnose that as a constraint violation.
3082bdd1243dSDimitry Andric     if (!DestType->isVoidType() && !DestType->isBooleanType() &&
3083bdd1243dSDimitry Andric         !DestType->isPointerType() && !DestType->isNullPtrType()) {
3084bdd1243dSDimitry Andric       Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3085bdd1243dSDimitry Andric           << /*nullptr to type*/ 0 << DestType;
3086bdd1243dSDimitry Andric       SrcExpr = ExprError();
3087bdd1243dSDimitry Andric       return;
3088bdd1243dSDimitry Andric     }
3089bdd1243dSDimitry Andric     if (!DestType->isNullPtrType()) {
3090bdd1243dSDimitry Andric       // Implicitly cast from the null pointer type to the type of the
3091bdd1243dSDimitry Andric       // destination.
3092bdd1243dSDimitry Andric       CastKind CK = DestType->isPointerType() ? CK_NullToPointer : CK_BitCast;
3093bdd1243dSDimitry Andric       SrcExpr = ImplicitCastExpr::Create(Self.Context, DestType, CK,
3094bdd1243dSDimitry Andric                                          SrcExpr.get(), nullptr, VK_PRValue,
3095bdd1243dSDimitry Andric                                          Self.CurFPFeatureOverrides());
3096bdd1243dSDimitry Andric     }
3097bdd1243dSDimitry Andric   }
3098bdd1243dSDimitry Andric   if (DestType->isNullPtrType() && !SrcType->isNullPtrType()) {
3099bdd1243dSDimitry Andric     Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)
3100bdd1243dSDimitry Andric         << /*type to nullptr*/ 1 << SrcType;
3101bdd1243dSDimitry Andric     SrcExpr = ExprError();
3102bdd1243dSDimitry Andric     return;
3103bdd1243dSDimitry Andric   }
3104bdd1243dSDimitry Andric 
31050b57cec5SDimitry Andric   if (DestType->isExtVectorType()) {
31060b57cec5SDimitry Andric     SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind);
31070b57cec5SDimitry Andric     return;
31080b57cec5SDimitry Andric   }
31090b57cec5SDimitry Andric 
3110fe6060f1SDimitry Andric   if (DestType->getAs<MatrixType>() || SrcType->getAs<MatrixType>()) {
3111fe6060f1SDimitry Andric     if (Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind))
3112fe6060f1SDimitry Andric       SrcExpr = ExprError();
3113fe6060f1SDimitry Andric     return;
3114fe6060f1SDimitry Andric   }
3115fe6060f1SDimitry Andric 
31160b57cec5SDimitry Andric   if (const VectorType *DestVecTy = DestType->getAs<VectorType>()) {
3117349cc55cSDimitry Andric     if (Self.CheckAltivecInitFromScalar(OpRange, DestType, SrcType)) {
3118349cc55cSDimitry Andric       SrcExpr = ExprError();
3119349cc55cSDimitry Andric       return;
3120349cc55cSDimitry Andric     }
3121fe6060f1SDimitry Andric     if (Self.ShouldSplatAltivecScalarInCast(DestVecTy) &&
31220b57cec5SDimitry Andric         (SrcType->isIntegerType() || SrcType->isFloatingType())) {
31230b57cec5SDimitry Andric       Kind = CK_VectorSplat;
31240b57cec5SDimitry Andric       SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());
31250b57cec5SDimitry Andric     } else if (Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {
31260b57cec5SDimitry Andric       SrcExpr = ExprError();
31270b57cec5SDimitry Andric     }
31280b57cec5SDimitry Andric     return;
31290b57cec5SDimitry Andric   }
31300b57cec5SDimitry Andric 
31310b57cec5SDimitry Andric   if (SrcType->isVectorType()) {
31320b57cec5SDimitry Andric     if (Self.CheckVectorCast(OpRange, SrcType, DestType, Kind))
31330b57cec5SDimitry Andric       SrcExpr = ExprError();
31340b57cec5SDimitry Andric     return;
31350b57cec5SDimitry Andric   }
31360b57cec5SDimitry Andric 
31370b57cec5SDimitry Andric   // The source and target types are both scalars, i.e.
31380b57cec5SDimitry Andric   //   - arithmetic types (fundamental, enum, and complex)
31390b57cec5SDimitry Andric   //   - all kinds of pointers
31400b57cec5SDimitry Andric   // Note that member pointers were filtered out with C++, above.
31410b57cec5SDimitry Andric 
31420b57cec5SDimitry Andric   if (isa<ObjCSelectorExpr>(SrcExpr.get())) {
31430b57cec5SDimitry Andric     Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr);
31440b57cec5SDimitry Andric     SrcExpr = ExprError();
31450b57cec5SDimitry Andric     return;
31460b57cec5SDimitry Andric   }
31470b57cec5SDimitry Andric 
31480b57cec5SDimitry Andric   // If either type is a pointer, the other type has to be either an
31490b57cec5SDimitry Andric   // integer or a pointer.
31500b57cec5SDimitry Andric   if (!DestType->isArithmeticType()) {
31510b57cec5SDimitry Andric     if (!SrcType->isIntegralType(Self.Context) && SrcType->isArithmeticType()) {
31520b57cec5SDimitry Andric       Self.Diag(SrcExpr.get()->getExprLoc(),
31530b57cec5SDimitry Andric                 diag::err_cast_pointer_from_non_pointer_int)
31540b57cec5SDimitry Andric         << SrcType << SrcExpr.get()->getSourceRange();
31550b57cec5SDimitry Andric       SrcExpr = ExprError();
31560b57cec5SDimitry Andric       return;
31570b57cec5SDimitry Andric     }
31585ffd83dbSDimitry Andric     checkIntToPointerCast(/* CStyle */ true, OpRange, SrcExpr.get(), DestType,
31595ffd83dbSDimitry Andric                           Self);
31600b57cec5SDimitry Andric   } else if (!SrcType->isArithmeticType()) {
31610b57cec5SDimitry Andric     if (!DestType->isIntegralType(Self.Context) &&
31620b57cec5SDimitry Andric         DestType->isArithmeticType()) {
31630b57cec5SDimitry Andric       Self.Diag(SrcExpr.get()->getBeginLoc(),
31640b57cec5SDimitry Andric                 diag::err_cast_pointer_to_non_pointer_int)
31650b57cec5SDimitry Andric           << DestType << SrcExpr.get()->getSourceRange();
31660b57cec5SDimitry Andric       SrcExpr = ExprError();
31670b57cec5SDimitry Andric       return;
31680b57cec5SDimitry Andric     }
31695ffd83dbSDimitry Andric 
31705ffd83dbSDimitry Andric     if ((Self.Context.getTypeSize(SrcType) >
31715ffd83dbSDimitry Andric          Self.Context.getTypeSize(DestType)) &&
31725ffd83dbSDimitry Andric         !DestType->isBooleanType()) {
31735ffd83dbSDimitry Andric       // C 6.3.2.3p6: Any pointer type may be converted to an integer type.
31745ffd83dbSDimitry Andric       // Except as previously specified, the result is implementation-defined.
31755ffd83dbSDimitry Andric       // If the result cannot be represented in the integer type, the behavior
31765ffd83dbSDimitry Andric       // is undefined. The result need not be in the range of values of any
31775ffd83dbSDimitry Andric       // integer type.
31785ffd83dbSDimitry Andric       unsigned Diag;
31795ffd83dbSDimitry Andric       if (SrcType->isVoidPointerType())
31805ffd83dbSDimitry Andric         Diag = DestType->isEnumeralType() ? diag::warn_void_pointer_to_enum_cast
31815ffd83dbSDimitry Andric                                           : diag::warn_void_pointer_to_int_cast;
31825ffd83dbSDimitry Andric       else if (DestType->isEnumeralType())
31835ffd83dbSDimitry Andric         Diag = diag::warn_pointer_to_enum_cast;
31845ffd83dbSDimitry Andric       else
31855ffd83dbSDimitry Andric         Diag = diag::warn_pointer_to_int_cast;
31865ffd83dbSDimitry Andric       Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;
31875ffd83dbSDimitry Andric     }
31880b57cec5SDimitry Andric   }
31890b57cec5SDimitry Andric 
3190fe6060f1SDimitry Andric   if (Self.getLangOpts().OpenCL && !Self.getOpenCLOptions().isAvailableOption(
3191fe6060f1SDimitry Andric                                        "cl_khr_fp16", Self.getLangOpts())) {
31920b57cec5SDimitry Andric     if (DestType->isHalfType()) {
31930b57cec5SDimitry Andric       Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half)
31940b57cec5SDimitry Andric           << DestType << SrcExpr.get()->getSourceRange();
31950b57cec5SDimitry Andric       SrcExpr = ExprError();
31960b57cec5SDimitry Andric       return;
31970b57cec5SDimitry Andric     }
31980b57cec5SDimitry Andric   }
31990b57cec5SDimitry Andric 
32000b57cec5SDimitry Andric   // ARC imposes extra restrictions on casts.
32010b57cec5SDimitry Andric   if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) {
3202*0fca6ea1SDimitry Andric     checkObjCConversion(CheckedConversionKind::CStyleCast);
32030b57cec5SDimitry Andric     if (SrcExpr.isInvalid())
32040b57cec5SDimitry Andric       return;
32050b57cec5SDimitry Andric 
32060b57cec5SDimitry Andric     const PointerType *CastPtr = DestType->getAs<PointerType>();
32070b57cec5SDimitry Andric     if (Self.getLangOpts().ObjCAutoRefCount && CastPtr) {
32080b57cec5SDimitry Andric       if (const PointerType *ExprPtr = SrcType->getAs<PointerType>()) {
32090b57cec5SDimitry Andric         Qualifiers CastQuals = CastPtr->getPointeeType().getQualifiers();
32100b57cec5SDimitry Andric         Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();
32110b57cec5SDimitry Andric         if (CastPtr->getPointeeType()->isObjCLifetimeType() &&
32120b57cec5SDimitry Andric             ExprPtr->getPointeeType()->isObjCLifetimeType() &&
32130b57cec5SDimitry Andric             !CastQuals.compatiblyIncludesObjCLifetime(ExprQuals)) {
32140b57cec5SDimitry Andric           Self.Diag(SrcExpr.get()->getBeginLoc(),
32150b57cec5SDimitry Andric                     diag::err_typecheck_incompatible_ownership)
32160b57cec5SDimitry Andric               << SrcType << DestType << Sema::AA_Casting
32170b57cec5SDimitry Andric               << SrcExpr.get()->getSourceRange();
32180b57cec5SDimitry Andric           return;
32190b57cec5SDimitry Andric         }
32200b57cec5SDimitry Andric       }
3221*0fca6ea1SDimitry Andric     } else if (!Self.ObjC().CheckObjCARCUnavailableWeakConversion(DestType,
3222*0fca6ea1SDimitry Andric                                                                   SrcType)) {
32230b57cec5SDimitry Andric       Self.Diag(SrcExpr.get()->getBeginLoc(),
32240b57cec5SDimitry Andric                 diag::err_arc_convesion_of_weak_unavailable)
32250b57cec5SDimitry Andric           << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange();
32260b57cec5SDimitry Andric       SrcExpr = ExprError();
32270b57cec5SDimitry Andric       return;
32280b57cec5SDimitry Andric     }
32290b57cec5SDimitry Andric   }
32300b57cec5SDimitry Andric 
3231bdd1243dSDimitry Andric   if (unsigned DiagID = checkCastFunctionType(Self, SrcExpr, DestType))
3232bdd1243dSDimitry Andric     Self.Diag(OpRange.getBegin(), DiagID) << SrcType << DestType << OpRange;
3233fe6060f1SDimitry Andric 
323481ad6265SDimitry Andric   if (isa<PointerType>(SrcType) && isa<PointerType>(DestType)) {
323581ad6265SDimitry Andric     QualType SrcTy = cast<PointerType>(SrcType)->getPointeeType();
323681ad6265SDimitry Andric     QualType DestTy = cast<PointerType>(DestType)->getPointeeType();
323781ad6265SDimitry Andric 
323881ad6265SDimitry Andric     const RecordDecl *SrcRD = SrcTy->getAsRecordDecl();
323981ad6265SDimitry Andric     const RecordDecl *DestRD = DestTy->getAsRecordDecl();
324081ad6265SDimitry Andric 
324181ad6265SDimitry Andric     if (SrcRD && DestRD && SrcRD->hasAttr<RandomizeLayoutAttr>() &&
324281ad6265SDimitry Andric         SrcRD != DestRD) {
324381ad6265SDimitry Andric       // The struct we are casting the pointer from was randomized.
324481ad6265SDimitry Andric       Self.Diag(OpRange.getBegin(), diag::err_cast_from_randomized_struct)
324581ad6265SDimitry Andric           << SrcType << DestType;
324681ad6265SDimitry Andric       SrcExpr = ExprError();
324781ad6265SDimitry Andric       return;
324881ad6265SDimitry Andric     }
324981ad6265SDimitry Andric   }
325081ad6265SDimitry Andric 
32510b57cec5SDimitry Andric   DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType);
32520b57cec5SDimitry Andric   DiagnoseCallingConvCast(Self, SrcExpr, DestType, OpRange);
32530b57cec5SDimitry Andric   DiagnoseBadFunctionCast(Self, SrcExpr, DestType);
32540b57cec5SDimitry Andric   Kind = Self.PrepareScalarCast(SrcExpr, DestType);
32550b57cec5SDimitry Andric   if (SrcExpr.isInvalid())
32560b57cec5SDimitry Andric     return;
32570b57cec5SDimitry Andric 
32580b57cec5SDimitry Andric   if (Kind == CK_BitCast)
32590b57cec5SDimitry Andric     checkCastAlign();
32600b57cec5SDimitry Andric }
32610b57cec5SDimitry Andric 
32620b57cec5SDimitry Andric void CastOperation::CheckBuiltinBitCast() {
32630b57cec5SDimitry Andric   QualType SrcType = SrcExpr.get()->getType();
3264a7dea167SDimitry Andric 
3265a7dea167SDimitry Andric   if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
3266a7dea167SDimitry Andric                                diag::err_typecheck_cast_to_incomplete) ||
3267a7dea167SDimitry Andric       Self.RequireCompleteType(OpRange.getBegin(), SrcType,
3268a7dea167SDimitry Andric                                diag::err_incomplete_type)) {
3269a7dea167SDimitry Andric     SrcExpr = ExprError();
3270a7dea167SDimitry Andric     return;
3271a7dea167SDimitry Andric   }
3272a7dea167SDimitry Andric 
3273fe6060f1SDimitry Andric   if (SrcExpr.get()->isPRValue())
32740b57cec5SDimitry Andric     SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),
32750b57cec5SDimitry Andric                                                   /*IsLValueReference=*/false);
32760b57cec5SDimitry Andric 
32770b57cec5SDimitry Andric   CharUnits DestSize = Self.Context.getTypeSizeInChars(DestType);
32780b57cec5SDimitry Andric   CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType);
32790b57cec5SDimitry Andric   if (DestSize != SourceSize) {
32800b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch)
32810b57cec5SDimitry Andric         << (int)SourceSize.getQuantity() << (int)DestSize.getQuantity();
32820b57cec5SDimitry Andric     SrcExpr = ExprError();
32830b57cec5SDimitry Andric     return;
32840b57cec5SDimitry Andric   }
32850b57cec5SDimitry Andric 
32860b57cec5SDimitry Andric   if (!DestType.isTriviallyCopyableType(Self.Context)) {
32870b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
32880b57cec5SDimitry Andric         << 1;
32890b57cec5SDimitry Andric     SrcExpr = ExprError();
32900b57cec5SDimitry Andric     return;
32910b57cec5SDimitry Andric   }
32920b57cec5SDimitry Andric 
32930b57cec5SDimitry Andric   if (!SrcType.isTriviallyCopyableType(Self.Context)) {
32940b57cec5SDimitry Andric     Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)
32950b57cec5SDimitry Andric         << 0;
32960b57cec5SDimitry Andric     SrcExpr = ExprError();
32970b57cec5SDimitry Andric     return;
32980b57cec5SDimitry Andric   }
32990b57cec5SDimitry Andric 
33000b57cec5SDimitry Andric   Kind = CK_LValueToRValueBitCast;
33010b57cec5SDimitry Andric }
33020b57cec5SDimitry Andric 
33030b57cec5SDimitry Andric /// DiagnoseCastQual - Warn whenever casts discards a qualifiers, be it either
33040b57cec5SDimitry Andric /// const, volatile or both.
33050b57cec5SDimitry Andric static void DiagnoseCastQual(Sema &Self, const ExprResult &SrcExpr,
33060b57cec5SDimitry Andric                              QualType DestType) {
33070b57cec5SDimitry Andric   if (SrcExpr.isInvalid())
33080b57cec5SDimitry Andric     return;
33090b57cec5SDimitry Andric 
33100b57cec5SDimitry Andric   QualType SrcType = SrcExpr.get()->getType();
33110b57cec5SDimitry Andric   if (!((SrcType->isAnyPointerType() && DestType->isAnyPointerType()) ||
33120b57cec5SDimitry Andric         DestType->isLValueReferenceType()))
33130b57cec5SDimitry Andric     return;
33140b57cec5SDimitry Andric 
33150b57cec5SDimitry Andric   QualType TheOffendingSrcType, TheOffendingDestType;
33160b57cec5SDimitry Andric   Qualifiers CastAwayQualifiers;
33170b57cec5SDimitry Andric   if (CastsAwayConstness(Self, SrcType, DestType, true, false,
33180b57cec5SDimitry Andric                          &TheOffendingSrcType, &TheOffendingDestType,
33190b57cec5SDimitry Andric                          &CastAwayQualifiers) !=
33200b57cec5SDimitry Andric       CastAwayConstnessKind::CACK_Similar)
33210b57cec5SDimitry Andric     return;
33220b57cec5SDimitry Andric 
33230b57cec5SDimitry Andric   // FIXME: 'restrict' is not properly handled here.
33240b57cec5SDimitry Andric   int qualifiers = -1;
33250b57cec5SDimitry Andric   if (CastAwayQualifiers.hasConst() && CastAwayQualifiers.hasVolatile()) {
33260b57cec5SDimitry Andric     qualifiers = 0;
33270b57cec5SDimitry Andric   } else if (CastAwayQualifiers.hasConst()) {
33280b57cec5SDimitry Andric     qualifiers = 1;
33290b57cec5SDimitry Andric   } else if (CastAwayQualifiers.hasVolatile()) {
33300b57cec5SDimitry Andric     qualifiers = 2;
33310b57cec5SDimitry Andric   }
33320b57cec5SDimitry Andric   // This is a variant of int **x; const int **y = (const int **)x;
33330b57cec5SDimitry Andric   if (qualifiers == -1)
33340b57cec5SDimitry Andric     Self.Diag(SrcExpr.get()->getBeginLoc(), diag::warn_cast_qual2)
33350b57cec5SDimitry Andric         << SrcType << DestType;
33360b57cec5SDimitry Andric   else
33370b57cec5SDimitry Andric     Self.Diag(SrcExpr.get()->getBeginLoc(), diag::warn_cast_qual)
33380b57cec5SDimitry Andric         << TheOffendingSrcType << TheOffendingDestType << qualifiers;
33390b57cec5SDimitry Andric }
33400b57cec5SDimitry Andric 
33410b57cec5SDimitry Andric ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc,
33420b57cec5SDimitry Andric                                      TypeSourceInfo *CastTypeInfo,
33430b57cec5SDimitry Andric                                      SourceLocation RPLoc,
33440b57cec5SDimitry Andric                                      Expr *CastExpr) {
33450b57cec5SDimitry Andric   CastOperation Op(*this, CastTypeInfo->getType(), CastExpr);
33460b57cec5SDimitry Andric   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
33470b57cec5SDimitry Andric   Op.OpRange = SourceRange(LPLoc, CastExpr->getEndLoc());
33480b57cec5SDimitry Andric 
33490b57cec5SDimitry Andric   if (getLangOpts().CPlusPlus) {
33500b57cec5SDimitry Andric     Op.CheckCXXCStyleCast(/*FunctionalCast=*/ false,
33510b57cec5SDimitry Andric                           isa<InitListExpr>(CastExpr));
33520b57cec5SDimitry Andric   } else {
33530b57cec5SDimitry Andric     Op.CheckCStyleCast();
33540b57cec5SDimitry Andric   }
33550b57cec5SDimitry Andric 
33560b57cec5SDimitry Andric   if (Op.SrcExpr.isInvalid())
33570b57cec5SDimitry Andric     return ExprError();
33580b57cec5SDimitry Andric 
33590b57cec5SDimitry Andric   // -Wcast-qual
33600b57cec5SDimitry Andric   DiagnoseCastQual(Op.Self, Op.SrcExpr, Op.DestType);
33610b57cec5SDimitry Andric 
3362e8d8bef9SDimitry Andric   return Op.complete(CStyleCastExpr::Create(
3363e8d8bef9SDimitry Andric       Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
3364e8d8bef9SDimitry Andric       &Op.BasePath, CurFPFeatureOverrides(), CastTypeInfo, LPLoc, RPLoc));
33650b57cec5SDimitry Andric }
33660b57cec5SDimitry Andric 
33670b57cec5SDimitry Andric ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo,
33680b57cec5SDimitry Andric                                             QualType Type,
33690b57cec5SDimitry Andric                                             SourceLocation LPLoc,
33700b57cec5SDimitry Andric                                             Expr *CastExpr,
33710b57cec5SDimitry Andric                                             SourceLocation RPLoc) {
33720b57cec5SDimitry Andric   assert(LPLoc.isValid() && "List-initialization shouldn't get here.");
33730b57cec5SDimitry Andric   CastOperation Op(*this, Type, CastExpr);
33740b57cec5SDimitry Andric   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
33755f757f3fSDimitry Andric   Op.OpRange = SourceRange(Op.DestRange.getBegin(), RPLoc);
33760b57cec5SDimitry Andric 
33770b57cec5SDimitry Andric   Op.CheckCXXCStyleCast(/*FunctionalCast=*/true, /*ListInit=*/false);
33780b57cec5SDimitry Andric   if (Op.SrcExpr.isInvalid())
33790b57cec5SDimitry Andric     return ExprError();
33800b57cec5SDimitry Andric 
33810b57cec5SDimitry Andric   auto *SubExpr = Op.SrcExpr.get();
33820b57cec5SDimitry Andric   if (auto *BindExpr = dyn_cast<CXXBindTemporaryExpr>(SubExpr))
33830b57cec5SDimitry Andric     SubExpr = BindExpr->getSubExpr();
33840b57cec5SDimitry Andric   if (auto *ConstructExpr = dyn_cast<CXXConstructExpr>(SubExpr))
33850b57cec5SDimitry Andric     ConstructExpr->setParenOrBraceRange(SourceRange(LPLoc, RPLoc));
33860b57cec5SDimitry Andric 
33875f757f3fSDimitry Andric   // -Wcast-qual
33885f757f3fSDimitry Andric   DiagnoseCastQual(Op.Self, Op.SrcExpr, Op.DestType);
33895f757f3fSDimitry Andric 
3390e8d8bef9SDimitry Andric   return Op.complete(CXXFunctionalCastExpr::Create(
3391e8d8bef9SDimitry Andric       Context, Op.ResultType, Op.ValueKind, CastTypeInfo, Op.Kind,
3392e8d8bef9SDimitry Andric       Op.SrcExpr.get(), &Op.BasePath, CurFPFeatureOverrides(), LPLoc, RPLoc));
33930b57cec5SDimitry Andric }
3394