diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp | 271 |
1 files changed, 157 insertions, 114 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp index 8bd9351..54683e1 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp @@ -49,7 +49,7 @@ namespace { : Self(S), SrcExpr(src), DestType(destType), ResultType(destType.getNonLValueExprType(S.Context)), ValueKind(Expr::getValueKindForType(destType)), - Kind(CK_Dependent) { + Kind(CK_Dependent), IsARCUnbridgedCast(false) { if (const BuiltinType *placeholder = src.get()->getType()->getAsPlaceholderType()) { @@ -67,6 +67,7 @@ namespace { CastKind Kind; BuiltinType::Kind PlaceholderKind; CXXCastPath BasePath; + bool IsARCUnbridgedCast; SourceRange OpRange; SourceRange DestRange; @@ -76,9 +77,23 @@ namespace { void CheckReinterpretCast(); void CheckStaticCast(); void CheckDynamicCast(); - void CheckCXXCStyleCast(bool FunctionalCast); + void CheckCXXCStyleCast(bool FunctionalCast, bool ListInitialization); void CheckCStyleCast(); + /// Complete an apparently-successful cast operation that yields + /// the given expression. + ExprResult complete(CastExpr *castExpr) { + // If this is an unbridged cast, wrap the result in an implicit + // cast that yields the unbridged-cast placeholder type. + if (IsARCUnbridgedCast) { + castExpr = ImplicitCastExpr::Create(Self.Context, + Self.Context.ARCUnbridgedCastTy, + CK_Dependent, castExpr, 0, + castExpr->getValueKind()); + } + return Self.Owned(castExpr); + } + // Internal convenience methods. /// Try to handle the given placeholder expression kind. Return @@ -103,8 +118,12 @@ namespace { } void checkObjCARCConversion(Sema::CheckedConversionKind CCK) { + assert(Self.getLangOpts().ObjCAutoRefCount); + Expr *src = SrcExpr.get(); - Self.CheckObjCARCConversion(OpRange, DestType, src, CCK); + if (Self.CheckObjCARCConversion(OpRange, DestType, src, CCK) == + Sema::ACR_unbridged) + IsARCUnbridgedCast = true; SrcExpr = src; } @@ -171,15 +190,15 @@ static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, Sema::CheckedConversionKind CCK, const SourceRange &OpRange, - unsigned &msg, - CastKind &Kind); + unsigned &msg, CastKind &Kind, + bool ListInitialization); static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, Sema::CheckedConversionKind CCK, const SourceRange &OpRange, - unsigned &msg, - CastKind &Kind, - CXXCastPath &BasePath); + unsigned &msg, CastKind &Kind, + CXXCastPath &BasePath, + bool ListInitialization); static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, unsigned &msg); static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, @@ -203,7 +222,7 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, if (D.isInvalidType()) return ExprError(); - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // Check that there are no default arguments (C++ only). CheckExtraCXXDefaultArguments(D); } @@ -237,9 +256,9 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, if (Op.SrcExpr.isInvalid()) return ExprError(); } - return Owned(CXXConstCastExpr::Create(Context, Op.ResultType, Op.ValueKind, - Op.SrcExpr.take(), DestTInfo, OpLoc, - Parens.getEnd())); + return Op.complete(CXXConstCastExpr::Create(Context, Op.ResultType, + Op.ValueKind, Op.SrcExpr.take(), DestTInfo, + OpLoc, Parens.getEnd())); case tok::kw_dynamic_cast: { if (!TypeDependent) { @@ -247,10 +266,10 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, if (Op.SrcExpr.isInvalid()) return ExprError(); } - return Owned(CXXDynamicCastExpr::Create(Context, Op.ResultType, - Op.ValueKind, Op.Kind, - Op.SrcExpr.take(), &Op.BasePath, - DestTInfo, OpLoc, Parens.getEnd())); + return Op.complete(CXXDynamicCastExpr::Create(Context, Op.ResultType, + Op.ValueKind, Op.Kind, Op.SrcExpr.take(), + &Op.BasePath, DestTInfo, + OpLoc, Parens.getEnd())); } case tok::kw_reinterpret_cast: { if (!TypeDependent) { @@ -258,11 +277,10 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, if (Op.SrcExpr.isInvalid()) return ExprError(); } - return Owned(CXXReinterpretCastExpr::Create(Context, Op.ResultType, - Op.ValueKind, Op.Kind, - Op.SrcExpr.take(), 0, - DestTInfo, OpLoc, - Parens.getEnd())); + return Op.complete(CXXReinterpretCastExpr::Create(Context, Op.ResultType, + Op.ValueKind, Op.Kind, Op.SrcExpr.take(), + 0, DestTInfo, OpLoc, + Parens.getEnd())); } case tok::kw_static_cast: { if (!TypeDependent) { @@ -271,21 +289,20 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, return ExprError(); } - return Owned(CXXStaticCastExpr::Create(Context, Op.ResultType, Op.ValueKind, - Op.Kind, Op.SrcExpr.take(), - &Op.BasePath, DestTInfo, OpLoc, - Parens.getEnd())); + return Op.complete(CXXStaticCastExpr::Create(Context, Op.ResultType, + Op.ValueKind, Op.Kind, Op.SrcExpr.take(), + &Op.BasePath, DestTInfo, + OpLoc, Parens.getEnd())); } } - - return ExprError(); } /// Try to diagnose a failed overloaded cast. Returns true if /// diagnostics were emitted. static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, SourceRange range, Expr *src, - QualType destType) { + QualType destType, + bool listInitialization) { switch (CT) { // These cast kinds don't consider user-defined conversions. case CT_Const: @@ -307,8 +324,9 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, InitializedEntity entity = InitializedEntity::InitializeTemporary(destType); InitializationKind initKind = (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(), - range) - : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range) + range, listInitialization) + : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range, + listInitialization) : InitializationKind::CreateCast(/*type range?*/ range); InitializationSequence sequence(S, entity, initKind, &src, 1); @@ -328,7 +346,6 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, switch (sequence.getFailedOverloadResult()) { case OR_Success: llvm_unreachable("successful failed overload"); - return false; case OR_No_Viable_Function: if (candidates.empty()) msg = diag::err_ovl_no_conversion_in_cast; @@ -352,21 +369,23 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, << CT << srcType << destType << range << src->getSourceRange(); - candidates.NoteCandidates(S, howManyCandidates, &src, 1); + candidates.NoteCandidates(S, howManyCandidates, src); return true; } /// Diagnose a failed cast. static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType, - SourceRange opRange, Expr *src, QualType destType) { + SourceRange opRange, Expr *src, QualType destType, + bool listInitialization) { if (src->getType() == S.Context.BoundMemberTy) { (void) S.CheckPlaceholderExpr(src); // will always fail return; } if (msg == diag::err_bad_cxx_cast_generic && - tryDiagnoseOverloadedCast(S, castType, opRange, src, destType)) + tryDiagnoseOverloadedCast(S, castType, opRange, src, destType, + listInitialization)) return; S.Diag(opRange.getBegin(), msg) << castType @@ -443,7 +462,7 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, // If the only checking we care about is for Objective-C lifetime qualifiers, // and we're not in ARC mode, there's nothing to check. if (!CheckCVR && CheckObjCLifetime && - !Self.Context.getLangOptions().ObjCAutoRefCount) + !Self.Context.getLangOpts().ObjCAutoRefCount) return false; // Casting away constness is defined in C++ 5.2.11p8 with reference to @@ -511,6 +530,13 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, /// Refer to C++ 5.2.7 for details. Dynamic casts are used mostly for runtime- /// checked downcasts in class hierarchies. void CastOperation::CheckDynamicCast() { + if (ValueKind == VK_RValue) + SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); + else if (isPlaceholder()) + SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take()); + if (SrcExpr.isInvalid()) // if conversion failed, don't report another error + return; + QualType OrigSrcType = SrcExpr.get()->getType(); QualType DestType = Self.Context.getCanonicalType(this->DestType); @@ -638,11 +664,12 @@ void CastOperation::CheckDynamicCast() { /// const char *str = "literal"; /// legacy_function(const_cast\<char*\>(str)); void CastOperation::CheckConstCast() { - if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload)) { + if (ValueKind == VK_RValue) SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); - if (SrcExpr.isInvalid()) // if conversion failed, don't report another error - return; - } + else if (isPlaceholder()) + SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take()); + if (SrcExpr.isInvalid()) // if conversion failed, don't report another error + return; unsigned msg = diag::err_bad_cxx_cast_generic; if (TryConstCast(Self, SrcExpr.get(), DestType, /*CStyle*/false, msg) != TC_Success @@ -657,11 +684,12 @@ void CastOperation::CheckConstCast() { /// like this: /// char *bytes = reinterpret_cast\<char*\>(int_ptr); void CastOperation::CheckReinterpretCast() { - if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload)) { + if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload)) SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take()); - if (SrcExpr.isInvalid()) // if conversion failed, don't report another error - return; - } + else + checkNonOverloadPlaceholders(); + if (SrcExpr.isInvalid()) // if conversion failed, don't report another error + return; unsigned msg = diag::err_bad_cxx_cast_generic; TryCastResult tcr = @@ -679,9 +707,10 @@ void CastOperation::CheckReinterpretCast() { Self.NoteAllOverloadCandidates(SrcExpr.get()); } else { - diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(), DestType); + diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(), + DestType, /*listInitialization=*/false); } - } else if (tcr == TC_Success && Self.getLangOptions().ObjCAutoRefCount) { + } else if (tcr == TC_Success && Self.getLangOpts().ObjCAutoRefCount) { checkObjCARCConversion(Sema::CCK_OtherCast); } } @@ -726,7 +755,7 @@ void CastOperation::CheckStaticCast() { unsigned msg = diag::err_bad_cxx_cast_generic; TryCastResult tcr = TryStaticCast(Self, SrcExpr, DestType, Sema::CCK_OtherCast, OpRange, msg, - Kind, BasePath); + Kind, BasePath, /*ListInitialization=*/false); if (tcr != TC_Success && msg != 0) { if (SrcExpr.isInvalid()) return; @@ -737,12 +766,13 @@ void CastOperation::CheckStaticCast() { << oe->getQualifierLoc().getSourceRange(); Self.NoteAllOverloadCandidates(SrcExpr.get()); } else { - diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr.get(), DestType); + diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr.get(), DestType, + /*listInitialization=*/false); } } else if (tcr == TC_Success) { if (Kind == CK_BitCast) checkCastAlign(); - if (Self.getLangOptions().ObjCAutoRefCount) + if (Self.getLangOpts().ObjCAutoRefCount) checkObjCARCConversion(Sema::CCK_OtherCast); } else if (Kind == CK_BitCast) { checkCastAlign(); @@ -756,8 +786,8 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, Sema::CheckedConversionKind CCK, const SourceRange &OpRange, unsigned &msg, - CastKind &Kind, - CXXCastPath &BasePath) { + CastKind &Kind, CXXCastPath &BasePath, + bool ListInitialization) { // Determine whether we have the semantics of a C-style cast. bool CStyle = (CCK == Sema::CCK_CStyleCast || CCK == Sema::CCK_FunctionalCast); @@ -782,23 +812,23 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, // C++ 5.2.9p5, reference downcast. // See the function for details. // DR 427 specifies that this is to be applied before paragraph 2. - tcr = TryStaticReferenceDowncast(Self, SrcExpr.get(), DestType, CStyle, OpRange, - msg, Kind, BasePath); + tcr = TryStaticReferenceDowncast(Self, SrcExpr.get(), DestType, CStyle, + OpRange, msg, Kind, BasePath); if (tcr != TC_NotApplicable) return tcr; // C++0x [expr.static.cast]p3: // A glvalue of type "cv1 T1" can be cast to type "rvalue reference to cv2 // T2" if "cv2 T2" is reference-compatible with "cv1 T1". - tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, Kind, BasePath, - msg); + tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, Kind, + BasePath, msg); if (tcr != TC_NotApplicable) return tcr; // C++ 5.2.9p2: An expression e can be explicitly converted to a type T // [...] if the declaration "T t(e);" is well-formed, [...]. tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CCK, OpRange, msg, - Kind); + Kind, ListInitialization); if (SrcExpr.isInvalid()) return TC_Failed; if (tcr != TC_NotApplicable) @@ -1269,7 +1299,7 @@ TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, Sema::CheckedConversionKind CCK, const SourceRange &OpRange, unsigned &msg, - CastKind &Kind) { + CastKind &Kind, bool ListInitialization) { if (DestType->isRecordType()) { if (Self.RequireCompleteType(OpRange.getBegin(), DestType, diag::err_bad_dynamic_cast_incomplete)) { @@ -1277,13 +1307,14 @@ TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, return TC_Failed; } } - + InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType); InitializationKind InitKind = (CCK == Sema::CCK_CStyleCast) - ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange) + ? InitializationKind::CreateCStyleCast(OpRange.getBegin(), OpRange, + ListInitialization) : (CCK == Sema::CCK_FunctionalCast) - ? InitializationKind::CreateFunctionalCast(OpRange) + ? InitializationKind::CreateFunctionalCast(OpRange, ListInitialization) : InitializationKind::CreateCast(OpRange); Expr *SrcExprRaw = SrcExpr.get(); InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExprRaw, 1); @@ -1497,6 +1528,8 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, case OK_BitField: inappropriate = "bit-field"; break; case OK_VectorComponent: inappropriate = "vector element"; break; case OK_ObjCProperty: inappropriate = "property expression"; break; + case OK_ObjCSubscript: inappropriate = "container subscripting expression"; + break; } if (inappropriate) { Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_reference) @@ -1545,7 +1578,8 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, } // A valid member pointer cast. - Kind = IsLValueCast? CK_LValueBitCast : CK_BitCast; + assert(!IsLValueCast); + Kind = CK_ReinterpretMemberPointer; return TC_Success; } @@ -1592,7 +1626,27 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, return TC_Failed; } - + + if (SrcType == DestType) { + // C++ 5.2.10p2 has a note that mentions that, subject to all other + // restrictions, a cast to the same type is allowed so long as it does not + // cast away constness. In C++98, the intent was not entirely clear here, + // since all other paragraphs explicitly forbid casts to the same type. + // C++11 clarifies this case with p2. + // + // The only allowed types are: integral, enumeration, pointer, or + // pointer-to-member types. We also won't restrict Obj-C pointers either. + Kind = CK_NoOp; + TryCastResult Result = TC_NotApplicable; + if (SrcType->isIntegralOrEnumerationType() || + SrcType->isAnyPointerType() || + SrcType->isMemberPointerType() || + SrcType->isBlockPointerType()) { + Result = TC_Success; + } + return Result; + } + bool destIsPtr = DestType->isAnyPointerType() || DestType->isBlockPointerType(); bool srcIsPtr = SrcType->isAnyPointerType() || @@ -1603,17 +1657,6 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, return TC_NotApplicable; } - if (SrcType == DestType) { - // C++ 5.2.10p2 has a note that mentions that, subject to all other - // restrictions, a cast to the same type is allowed. The intent is not - // entirely clear here, since all other paragraphs explicitly forbid casts - // to the same type. However, the behavior of compilers is pretty consistent - // on this point: allow same-type conversion if the involved types are - // pointers, disallow otherwise. - Kind = CK_NoOp; - return TC_Success; - } - if (DestType->isIntegralType(Self.Context)) { assert(srcIsPtr && "One type must be a pointer"); // C++ 5.2.10p4: A pointer can be explicitly converted to any integral @@ -1621,7 +1664,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, // integral type size doesn't matter. if ((Self.Context.getTypeSize(SrcType) > Self.Context.getTypeSize(DestType)) && - !Self.getLangOptions().MicrosoftExt) { + !Self.getLangOpts().MicrosoftExt) { msg = diag::err_bad_reinterpret_cast_small_int; return TC_Failed; } @@ -1694,15 +1737,19 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, // casting the return value of dlsym() and GetProcAddress(). // FIXME: Conditionally-supported behavior should be configurable in the // TargetInfo or similar. - if (!Self.getLangOptions().CPlusPlus0x) - Self.Diag(OpRange.getBegin(), diag::ext_cast_fn_obj) << OpRange; + Self.Diag(OpRange.getBegin(), + Self.getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj) + << OpRange; return TC_Success; } if (DestType->isFunctionPointerType()) { // See above. - if (!Self.getLangOptions().CPlusPlus0x) - Self.Diag(OpRange.getBegin(), diag::ext_cast_fn_obj) << OpRange; + Self.Diag(OpRange.getBegin(), + Self.getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj) + << OpRange; return TC_Success; } @@ -1714,7 +1761,8 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, return TC_Success; } -void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle) { +void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, + bool ListInitialization) { // Handle placeholders. if (isPlaceholder()) { // C-style casts can resolve __unknown_any types. @@ -1728,7 +1776,7 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle) { checkNonOverloadPlaceholders(); if (SrcExpr.isInvalid()) return; - } + } // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". // This test is outside everything else because it's the only case where @@ -1797,7 +1845,7 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle) { if (tcr == TC_NotApplicable) { // ... or if that is not possible, a static_cast, ignoring const, ... tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange, - msg, Kind, BasePath); + msg, Kind, BasePath, ListInitialization); if (SrcExpr.isInvalid()) return; @@ -1810,7 +1858,7 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle) { } } - if (Self.getLangOptions().ObjCAutoRefCount && tcr == TC_Success) + if (Self.getLangOpts().ObjCAutoRefCount && tcr == TC_Success) checkObjCARCConversion(CCK); if (tcr != TC_Success && msg != 0) { @@ -1826,7 +1874,7 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle) { } else { diagnoseBadCast(Self, msg, (FunctionalStyle ? CT_Functional : CT_CStyle), - OpRange, SrcExpr.get(), DestType); + OpRange, SrcExpr.get(), DestType, ListInitialization); } } else if (Kind == CK_BitCast) { checkCastAlign(); @@ -1839,26 +1887,15 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle) { /// Check the semantics of a C-style cast operation, in C. void CastOperation::CheckCStyleCast() { - assert(!Self.getLangOptions().CPlusPlus); + assert(!Self.getLangOpts().CPlusPlus); - // Handle placeholders. - if (isPlaceholder()) { - // C-style casts can resolve __unknown_any types. - if (claimPlaceholder(BuiltinType::UnknownAny)) { - SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType, - SrcExpr.get(), Kind, - ValueKind, BasePath); - return; - } - - // We allow overloads in C, but we don't allow them to be resolved - // by anything except calls. - SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take()); - if (SrcExpr.isInvalid()) - return; - } - - assert(!isPlaceholder()); + // C-style casts can resolve __unknown_any types. + if (claimPlaceholder(BuiltinType::UnknownAny)) { + SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType, + SrcExpr.get(), Kind, + ValueKind, BasePath); + return; + } // C99 6.5.4p2: the cast type needs to be void or scalar and the expression // type needs to be scalar. @@ -1878,6 +1915,12 @@ void CastOperation::CheckCStyleCast() { return; QualType SrcType = SrcExpr.get()->getType(); + // You can cast an _Atomic(T) to anything you can cast a T to. + if (const AtomicType *AtomicSrcType = SrcType->getAs<AtomicType>()) + SrcType = AtomicSrcType->getValueType(); + + assert(!SrcType->isPlaceholderType()); + if (Self.RequireCompleteType(OpRange.getBegin(), DestType, diag::err_typecheck_cast_to_incomplete)) { SrcExpr = ExprError(); @@ -1983,14 +2026,14 @@ void CastOperation::CheckCStyleCast() { DestType->isArithmeticType()) { Self.Diag(SrcExpr.get()->getLocStart(), diag::err_cast_pointer_to_non_pointer_int) - << SrcType << SrcExpr.get()->getSourceRange(); + << DestType << SrcExpr.get()->getSourceRange(); SrcExpr = ExprError(); return; } } // ARC imposes extra restrictions on casts. - if (Self.getLangOptions().ObjCAutoRefCount) { + if (Self.getLangOpts().ObjCAutoRefCount) { checkObjCARCConversion(Sema::CCK_CStyleCast); if (SrcExpr.isInvalid()) return; @@ -2035,8 +2078,9 @@ ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc, Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange(); Op.OpRange = SourceRange(LPLoc, CastExpr->getLocEnd()); - if (getLangOptions().CPlusPlus) { - Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ false); + if (getLangOpts().CPlusPlus) { + Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ false, + isa<InitListExpr>(CastExpr)); } else { Op.CheckCStyleCast(); } @@ -2044,26 +2088,25 @@ ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc, if (Op.SrcExpr.isInvalid()) return ExprError(); - return Owned(CStyleCastExpr::Create(Context, Op.ResultType, Op.ValueKind, - Op.Kind, Op.SrcExpr.take(), &Op.BasePath, - CastTypeInfo, LPLoc, RPLoc)); + return Op.complete(CStyleCastExpr::Create(Context, Op.ResultType, + Op.ValueKind, Op.Kind, Op.SrcExpr.take(), + &Op.BasePath, CastTypeInfo, LPLoc, RPLoc)); } ExprResult Sema::BuildCXXFunctionalCastExpr(TypeSourceInfo *CastTypeInfo, SourceLocation LPLoc, Expr *CastExpr, SourceLocation RPLoc) { + assert(LPLoc.isValid() && "List-initialization shouldn't get here."); CastOperation Op(*this, CastTypeInfo->getType(), CastExpr); Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange(); Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getLocEnd()); - Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ true); + Op.CheckCXXCStyleCast(/*FunctionalStyle=*/true, /*ListInit=*/false); if (Op.SrcExpr.isInvalid()) return ExprError(); - return Owned(CXXFunctionalCastExpr::Create(Context, Op.ResultType, - Op.ValueKind, CastTypeInfo, - Op.DestRange.getBegin(), - Op.Kind, Op.SrcExpr.take(), - &Op.BasePath, RPLoc)); + return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType, + Op.ValueKind, CastTypeInfo, Op.DestRange.getBegin(), + Op.Kind, Op.SrcExpr.take(), &Op.BasePath, RPLoc)); } |