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