diff options
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 322 |
1 files changed, 183 insertions, 139 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index e804fcd60c74..3300444a1c1e 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -295,6 +295,12 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, SourceLocation RParenLoc) { bool isUnevaluatedOperand = true; if (E && !E->isTypeDependent()) { + if (E->getType()->isPlaceholderType()) { + ExprResult result = CheckPlaceholderExpr(E); + if (result.isInvalid()) return ExprError(); + E = result.take(); + } + QualType T = E->getType(); if (const RecordType *RecordT = T->getAs<RecordType>()) { CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl()); @@ -325,7 +331,7 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals); if (!Context.hasSameType(T, UnqualT)) { T = UnqualT; - E = ImpCastExprToType(E, UnqualT, CK_NoOp, CastCategory(E)).take(); + E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).take(); } } @@ -545,7 +551,7 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, // or "pointer to function returning T", [...] if (E->getType().hasQualifiers()) E = ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp, - CastCategory(E)).take(); + E->getValueKind()).take(); ExprResult Res = DefaultFunctionArrayConversion(E); if (Res.isInvalid()) @@ -739,27 +745,10 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, // If the expression list is a single expression, the type conversion // expression is equivalent (in definedness, and if defined in meaning) to the // corresponding cast expression. - // if (NumExprs == 1) { - CastKind Kind = CK_Invalid; - ExprValueKind VK = VK_RValue; - CXXCastPath BasePath; - ExprResult CastExpr = - CheckCastTypes(TInfo->getTypeLoc().getBeginLoc(), - TInfo->getTypeLoc().getSourceRange(), Ty, Exprs[0], - Kind, VK, BasePath, - /*FunctionalStyle=*/true); - if (CastExpr.isInvalid()) - return ExprError(); - Exprs[0] = CastExpr.take(); - + Expr *Arg = Exprs[0]; exprs.release(); - - return Owned(CXXFunctionalCastExpr::Create(Context, - Ty.getNonLValueExprType(Context), - VK, TInfo, TyBeginLoc, Kind, - Exprs[0], &BasePath, - RParenLoc)); + return BuildCXXFunctionalCastExpr(TInfo, LParenLoc, Arg, RParenLoc); } InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo); @@ -1058,7 +1047,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, UsualArrayDeleteWantsSize = doesUsualArrayDeleteWantSize(*this, StartLoc, AllocType); - llvm::SmallVector<Expr *, 8> AllPlaceArgs; + SmallVector<Expr *, 8> AllPlaceArgs; if (OperatorNew) { // Add default arguments, if any. const FunctionProtoType *Proto = @@ -1079,6 +1068,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, bool Init = ConstructorLParen.isValid(); // --- Choosing a constructor --- CXXConstructorDecl *Constructor = 0; + bool HadMultipleCandidates = false; Expr **ConsArgs = (Expr**)ConstructorArgs.get(); unsigned NumConsArgs = ConstructorArgs.size(); ASTOwningVector<Expr*> ConvertedConstructorArgs(*this); @@ -1125,6 +1115,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(FullInitExpr)) { Constructor = Construct->getConstructor(); + HadMultipleCandidates = Construct->hadMultipleCandidates(); for (CXXConstructExpr::arg_iterator A = Construct->arg_begin(), AEnd = Construct->arg_end(); A != AEnd; ++A) @@ -1166,7 +1157,9 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew, PlaceArgs, NumPlaceArgs, TypeIdParens, ArraySize, Constructor, Init, - ConsArgs, NumConsArgs, OperatorDelete, + ConsArgs, NumConsArgs, + HadMultipleCandidates, + OperatorDelete, UsualArrayDeleteWantsSize, ResultType, AllocTypeInfo, StartLoc, @@ -1246,12 +1239,12 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, // 3) The first argument is always size_t. Append the arguments from the // placement form. - llvm::SmallVector<Expr*, 8> AllocArgs(1 + NumPlaceArgs); + SmallVector<Expr*, 8> AllocArgs(1 + NumPlaceArgs); // We don't care about the actual value of this argument. // FIXME: Should the Sema create the expression and embed it in the syntax // tree? Or should the consumer just recalculate the value? IntegerLiteral Size(Context, llvm::APInt::getNullValue( - Context.Target.getPointerWidth(0)), + Context.getTargetInfo().getPointerWidth(0)), Context.getSizeType(), SourceLocation()); AllocArgs[0] = &Size; @@ -1325,7 +1318,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, FoundDelete.suppressDiagnostics(); - llvm::SmallVector<std::pair<DeclAccessPair,FunctionDecl*>, 2> Matches; + SmallVector<std::pair<DeclAccessPair,FunctionDecl*>, 2> Matches; // Whether we're looking for a placement operator delete is dictated // by whether we selected a placement operator new, not by whether @@ -1352,7 +1345,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, const FunctionProtoType *Proto = OperatorNew->getType()->getAs<FunctionProtoType>(); - llvm::SmallVector<QualType, 4> ArgTypes; + SmallVector<QualType, 4> ArgTypes; ArgTypes.push_back(Context.VoidPtrTy); for (unsigned I = 1, N = Proto->getNumArgs(); I < N; ++I) ArgTypes.push_back(Proto->getArgType(I)); @@ -1525,8 +1518,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, return true; } } - assert(false && "Unreachable, bad result from BestViableFunction"); - return true; + llvm_unreachable("Unreachable, bad result from BestViableFunction"); } @@ -1671,7 +1663,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, SourceLocation(), 0, Argument, /*TInfo=*/0, SC_None, SC_None, 0); - Alloc->setParams(&Param, 1); + Alloc->setParams(Param); // FIXME: Also add this declaration to the IdentifierResolver, but // make sure it is at the end of the chain to coincide with the @@ -1691,7 +1683,7 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, Found.suppressDiagnostics(); - llvm::SmallVector<DeclAccessPair,4> Matches; + SmallVector<DeclAccessPair,4> Matches; for (LookupResult::iterator F = Found.begin(), FEnd = Found.end(); F != FEnd; ++F) { NamedDecl *ND = (*F)->getUnderlyingDecl(); @@ -1727,7 +1719,7 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found) << Name << RD; - for (llvm::SmallVectorImpl<DeclAccessPair>::iterator + for (SmallVectorImpl<DeclAccessPair>::iterator F = Matches.begin(), FEnd = Matches.end(); F != FEnd; ++F) Diag((*F)->getUnderlyingDecl()->getLocation(), diag::note_member_declared_here) << Name; @@ -1792,7 +1784,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, PDiag(diag::err_delete_incomplete_class_type))) return ExprError(); - llvm::SmallVector<CXXConversionDecl*, 4> ObjectPtrConversions; + SmallVector<CXXConversionDecl*, 4> ObjectPtrConversions; CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); const UnresolvedSetImpl *Conversions = RD->getVisibleConversionFunctions(); @@ -1840,24 +1832,32 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, << Type << Ex.get()->getSourceRange()); QualType Pointee = Type->getAs<PointerType>()->getPointeeType(); + QualType PointeeElem = Context.getBaseElementType(Pointee); + + if (unsigned AddressSpace = Pointee.getAddressSpace()) + return Diag(Ex.get()->getLocStart(), + diag::err_address_space_qualified_delete) + << Pointee.getUnqualifiedType() << AddressSpace; + + CXXRecordDecl *PointeeRD = 0; if (Pointee->isVoidType() && !isSFINAEContext()) { // The C++ standard bans deleting a pointer to a non-object type, which // effectively bans deletion of "void*". However, most compilers support // this, so we treat it as a warning unless we're in a SFINAE context. Diag(StartLoc, diag::ext_delete_void_ptr_operand) << Type << Ex.get()->getSourceRange(); - } else if (Pointee->isFunctionType() || Pointee->isVoidType()) + } else if (Pointee->isFunctionType() || Pointee->isVoidType()) { return ExprError(Diag(StartLoc, diag::err_delete_operand) << Type << Ex.get()->getSourceRange()); - else if (!Pointee->isDependentType() && - RequireCompleteType(StartLoc, Pointee, - PDiag(diag::warn_delete_incomplete) - << Ex.get()->getSourceRange())) - return ExprError(); - else if (unsigned AddressSpace = Pointee.getAddressSpace()) - return Diag(Ex.get()->getLocStart(), - diag::err_address_space_qualified_delete) - << Pointee.getUnqualifiedType() << AddressSpace; + } else if (!Pointee->isDependentType()) { + if (!RequireCompleteType(StartLoc, Pointee, + PDiag(diag::warn_delete_incomplete) + << Ex.get()->getSourceRange())) { + if (const RecordType *RT = PointeeElem->getAs<RecordType>()) + PointeeRD = cast<CXXRecordDecl>(RT->getDecl()); + } + } + // C++ [expr.delete]p2: // [Note: a pointer to a const type can be the operand of a // delete-expression; it is not necessary to cast away the constness @@ -1877,12 +1877,10 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName( ArrayForm ? OO_Array_Delete : OO_Delete); - QualType PointeeElem = Context.getBaseElementType(Pointee); - if (const RecordType *RT = PointeeElem->getAs<RecordType>()) { - CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - + if (PointeeRD) { if (!UseGlobal && - FindDeallocationFunction(StartLoc, RD, DeleteName, OperatorDelete)) + FindDeallocationFunction(StartLoc, PointeeRD, DeleteName, + OperatorDelete)) return ExprError(); // If we're allocating an array of records, check whether the @@ -1900,8 +1898,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, UsualArrayDeleteWantsSize = (OperatorDelete->getNumParams() == 2); } - if (!RD->hasTrivialDestructor()) - if (CXXDestructorDecl *Dtor = LookupDestructor(RD)) { + if (!PointeeRD->hasTrivialDestructor()) + if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) { MarkDeclarationReferenced(StartLoc, const_cast<CXXDestructorDecl*>(Dtor)); DiagnoseUseOfDecl(Dtor, StartLoc); @@ -1915,10 +1913,20 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, // behavior is undefined. // // Note: a final class cannot be derived from, no issue there - if (!ArrayForm && RD->isPolymorphic() && !RD->hasAttr<FinalAttr>()) { - CXXDestructorDecl *dtor = RD->getDestructor(); - if (!dtor || !dtor->isVirtual()) - Diag(StartLoc, diag::warn_delete_non_virtual_dtor) << PointeeElem; + if (PointeeRD->isPolymorphic() && !PointeeRD->hasAttr<FinalAttr>()) { + CXXDestructorDecl *dtor = PointeeRD->getDestructor(); + if (dtor && !dtor->isVirtual()) { + if (PointeeRD->isAbstract()) { + // If the class is abstract, we warn by default, because we're + // sure the code has undefined behavior. + Diag(StartLoc, diag::warn_delete_abstract_non_virtual_dtor) + << PointeeElem; + } else if (!ArrayForm) { + // Otherwise, if this is not an array delete, it's a bit suspect, + // but not necessarily wrong. + Diag(StartLoc, diag::warn_delete_non_virtual_dtor) << PointeeElem; + } + } } } else if (getLangOptions().ObjCAutoRefCount && @@ -1944,9 +1952,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, MarkDeclarationReferenced(StartLoc, OperatorDelete); // Check access and ambiguity of operator delete and destructor. - if (const RecordType *RT = PointeeElem->getAs<RecordType>()) { - CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - if (CXXDestructorDecl *Dtor = LookupDestructor(RD)) { + if (PointeeRD) { + if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) { CheckDestructorAccess(Ex.get()->getExprLoc(), Dtor, PDiag(diag::err_access_dtor) << PointeeElem); } @@ -2026,12 +2033,20 @@ Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) { = ToPtrType->getPointeeType()->getAs<BuiltinType>()) { // This conversion is considered only when there is an // explicit appropriate pointer target type (C++ 4.2p2). - if (!ToPtrType->getPointeeType().hasQualifiers() && - ((StrLit->isWide() && ToPointeeType->isWideCharType()) || - (!StrLit->isWide() && - (ToPointeeType->getKind() == BuiltinType::Char_U || - ToPointeeType->getKind() == BuiltinType::Char_S)))) - return true; + if (!ToPtrType->getPointeeType().hasQualifiers()) { + switch (StrLit->getKind()) { + case StringLiteral::UTF8: + case StringLiteral::UTF16: + case StringLiteral::UTF32: + // We don't allow UTF literals to be implicitly converted + break; + case StringLiteral::Ascii: + return (ToPointeeType->getKind() == BuiltinType::Char_U || + ToPointeeType->getKind() == BuiltinType::Char_S); + case StringLiteral::Wide: + return ToPointeeType->isWideCharType(); + } + } } return false; @@ -2042,23 +2057,28 @@ static ExprResult BuildCXXCastArgument(Sema &S, QualType Ty, CastKind Kind, CXXMethodDecl *Method, - NamedDecl *FoundDecl, + DeclAccessPair FoundDecl, + bool HadMultipleCandidates, Expr *From) { switch (Kind) { - default: assert(0 && "Unhandled cast kind!"); + default: llvm_unreachable("Unhandled cast kind!"); case CK_ConstructorConversion: { + CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Method); ASTOwningVector<Expr*> ConstructorArgs(S); - if (S.CompleteConstructorCall(cast<CXXConstructorDecl>(Method), + if (S.CompleteConstructorCall(Constructor, MultiExprArg(&From, 1), CastLoc, ConstructorArgs)) return ExprError(); - ExprResult Result = - S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method), - move_arg(ConstructorArgs), - /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, - SourceRange()); + S.CheckConstructorAccess(CastLoc, Constructor, Constructor->getAccess(), + S.PDiag(diag::err_access_ctor)); + + ExprResult Result + = S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method), + move_arg(ConstructorArgs), + HadMultipleCandidates, /*ZeroInit*/ false, + CXXConstructExpr::CK_Complete, SourceRange()); if (Result.isInvalid()) return ExprError(); @@ -2069,10 +2089,13 @@ static ExprResult BuildCXXCastArgument(Sema &S, assert(!From->getType()->isPointerType() && "Arg can't have pointer type!"); // Create an implicit call expr that calls it. - ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Method); + ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Method, + HadMultipleCandidates); if (Result.isInvalid()) return ExprError(); + S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ 0, FoundDecl); + return S.MaybeBindToTemporary(Result.get()); } } @@ -2138,6 +2161,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, ToType.getNonReferenceType(), CastKind, cast<CXXMethodDecl>(FD), ICS.UserDefined.FoundConversionFunction, + ICS.UserDefined.HadMultipleCandidates, From); if (CastArg.isInvalid()) @@ -2156,8 +2180,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, return ExprError(); case ImplicitConversionSequence::EllipsisConversion: - assert(false && "Cannot perform an ellipsis conversion"); - return Owned(From); + llvm_unreachable("Cannot perform an ellipsis conversion"); case ImplicitConversionSequence::BadConversion: return ExprError(); @@ -2198,6 +2221,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(), ToType, SCS.CopyConstructor, move_arg(ConstructorArgs), + /*HadMultipleCandidates*/ false, /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, SourceRange()); @@ -2205,6 +2229,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(), ToType, SCS.CopyConstructor, MultiExprArg(*this, &From, 1), + /*HadMultipleCandidates*/ false, /*ZeroInit*/ false, CXXConstructExpr::CK_Complete, SourceRange()); @@ -2241,9 +2266,6 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, if (!From->isGLValue()) break; } - // Check for trivial buffer overflows. - CheckArrayAccess(From); - FromType = FromType.getUnqualifiedType(); From = ImplicitCastExpr::Create(Context, FromType, CK_LValueToRValue, From, 0, VK_RValue); @@ -2262,8 +2284,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, break; default: - assert(false && "Improper first standard conversion"); - break; + llvm_unreachable("Improper first standard conversion"); } // Perform the second implicit conversion @@ -2340,12 +2361,12 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, Diag(From->getSourceRange().getBegin(), diag::ext_typecheck_convert_incompatible_pointer) << ToType << From->getType() << Action - << From->getSourceRange(); + << From->getSourceRange() << 0; else Diag(From->getSourceRange().getBegin(), diag::ext_typecheck_convert_incompatible_pointer) << From->getType() << ToType << Action - << From->getSourceRange(); + << From->getSourceRange() << 0; if (From->getType()->isObjCObjectPointerType() && ToType->isObjCObjectPointerType()) @@ -2354,20 +2375,29 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, else if (getLangOptions().ObjCAutoRefCount && !CheckObjCARCUnavailableWeakConversion(ToType, From->getType())) { - if (Action == AA_Initializing) - Diag(From->getSourceRange().getBegin(), - diag::err_arc_weak_unavailable_assign); - else - Diag(From->getSourceRange().getBegin(), - diag::err_arc_convesion_of_weak_unavailable) - << (Action == AA_Casting) << From->getType() << ToType - << From->getSourceRange(); - } + if (Action == AA_Initializing) + Diag(From->getSourceRange().getBegin(), + diag::err_arc_weak_unavailable_assign); + else + Diag(From->getSourceRange().getBegin(), + diag::err_arc_convesion_of_weak_unavailable) + << (Action == AA_Casting) << From->getType() << ToType + << From->getSourceRange(); + } CastKind Kind = CK_Invalid; CXXCastPath BasePath; if (CheckPointerConversion(From, ToType, Kind, BasePath, CStyle)) return ExprError(); + + // Make sure we extend blocks if necessary. + // FIXME: doing this here is really ugly. + if (Kind == CK_BlockPointerToObjCPointerCast) { + ExprResult E = From; + (void) PrepareCastToObjCObjectPointer(E); + From = E.take(); + } + From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK) .take(); break; @@ -2386,6 +2416,12 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, } case ICK_Boolean_Conversion: + // Perform half-to-boolean conversion via float. + if (From->getType()->isHalfType()) { + From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).take(); + FromType = Context.FloatTy; + } + From = ImpCastExprToType(From, Context.BoolTy, ScalarTypeToBooleanCastKind(FromType), VK_RValue, /*BasePath=*/0, CCK).take(); @@ -2402,7 +2438,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, return ExprError(); From = ImpCastExprToType(From, ToType.getNonReferenceType(), - CK_DerivedToBase, CastCategory(From), + CK_DerivedToBase, From->getValueKind(), &BasePath, CCK).take(); break; } @@ -2493,8 +2529,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, case ICK_Function_To_Pointer: case ICK_Qualification: case ICK_Num_Conversion_Kinds: - assert(false && "Improper second standard conversion"); - break; + llvm_unreachable("Improper second standard conversion"); } switch (SCS.Third) { @@ -2506,7 +2541,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, // The qualification keeps the category of the inner expression, unless the // target type isn't a reference. ExprValueKind VK = ToType->isReferenceType() ? - CastCategory(From) : VK_RValue; + From->getValueKind() : VK_RValue; From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context), CK_NoOp, VK, /*BasePath=*/0, CCK).take(); @@ -2519,8 +2554,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, } default: - assert(false && "Improper third standard conversion"); - break; + llvm_unreachable("Improper third standard conversion"); } return Owned(From); @@ -2835,8 +2869,12 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, LookupResult Res(Self, DeclarationNameInfo(Name, KeyLoc), Sema::LookupOrdinaryName); if (Self.LookupQualifiedName(Res, RD)) { + Res.suppressDiagnostics(); for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end(); Op != OpEnd; ++Op) { + if (isa<FunctionTemplateDecl>(*Op)) + continue; + CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op); if (Operator->isCopyAssignmentOperator()) { FoundAssign = true; @@ -2849,7 +2887,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, } } } - + return FoundAssign; } return false; @@ -3240,34 +3278,34 @@ ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET, RParen, Context.BoolTy)); } -QualType Sema::CheckPointerToMemberOperands(ExprResult &lex, ExprResult &rex, +QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK, SourceLocation Loc, bool isIndirect) { - assert(!lex.get()->getType()->isPlaceholderType() && - !rex.get()->getType()->isPlaceholderType() && + assert(!LHS.get()->getType()->isPlaceholderType() && + !RHS.get()->getType()->isPlaceholderType() && "placeholders should have been weeded out by now"); // The LHS undergoes lvalue conversions if this is ->*. if (isIndirect) { - lex = DefaultLvalueConversion(lex.take()); - if (lex.isInvalid()) return QualType(); + LHS = DefaultLvalueConversion(LHS.take()); + if (LHS.isInvalid()) return QualType(); } // The RHS always undergoes lvalue conversions. - rex = DefaultLvalueConversion(rex.take()); - if (rex.isInvalid()) return QualType(); + RHS = DefaultLvalueConversion(RHS.take()); + if (RHS.isInvalid()) return QualType(); const char *OpSpelling = isIndirect ? "->*" : ".*"; // C++ 5.5p2 // The binary operator .* [p3: ->*] binds its second operand, which shall // be of type "pointer to member of T" (where T is a completely-defined // class type) [...] - QualType RType = rex.get()->getType(); - const MemberPointerType *MemPtr = RType->getAs<MemberPointerType>(); + QualType RHSType = RHS.get()->getType(); + const MemberPointerType *MemPtr = RHSType->getAs<MemberPointerType>(); if (!MemPtr) { Diag(Loc, diag::err_bad_memptr_rhs) - << OpSpelling << RType << rex.get()->getSourceRange(); + << OpSpelling << RHSType << RHS.get()->getSourceRange(); return QualType(); } @@ -3283,21 +3321,21 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &lex, ExprResult &rex, // [...] to its first operand, which shall be of class T or of a class of // which T is an unambiguous and accessible base class. [p3: a pointer to // such a class] - QualType LType = lex.get()->getType(); + QualType LHSType = LHS.get()->getType(); if (isIndirect) { - if (const PointerType *Ptr = LType->getAs<PointerType>()) - LType = Ptr->getPointeeType(); + if (const PointerType *Ptr = LHSType->getAs<PointerType>()) + LHSType = Ptr->getPointeeType(); else { Diag(Loc, diag::err_bad_memptr_lhs) - << OpSpelling << 1 << LType + << OpSpelling << 1 << LHSType << FixItHint::CreateReplacement(SourceRange(Loc), ".*"); return QualType(); } } - if (!Context.hasSameUnqualifiedType(Class, LType)) { + if (!Context.hasSameUnqualifiedType(Class, LHSType)) { // If we want to check the hierarchy, we need a complete type. - if (RequireCompleteType(Loc, LType, PDiag(diag::err_bad_memptr_lhs) + if (RequireCompleteType(Loc, LHSType, PDiag(diag::err_bad_memptr_lhs) << OpSpelling << (int)isIndirect)) { return QualType(); } @@ -3305,23 +3343,23 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &lex, ExprResult &rex, /*DetectVirtual=*/false); // FIXME: Would it be useful to print full ambiguity paths, or is that // overkill? - if (!IsDerivedFrom(LType, Class, Paths) || + if (!IsDerivedFrom(LHSType, Class, Paths) || Paths.isAmbiguous(Context.getCanonicalType(Class))) { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling - << (int)isIndirect << lex.get()->getType(); + << (int)isIndirect << LHS.get()->getType(); return QualType(); } // Cast LHS to type of use. QualType UseType = isIndirect ? Context.getPointerType(Class) : Class; - ExprValueKind VK = - isIndirect ? VK_RValue : CastCategory(lex.get()); + ExprValueKind VK = isIndirect ? VK_RValue : LHS.get()->getValueKind(); CXXCastPath BasePath; BuildBasePathArray(Paths, BasePath); - lex = ImpCastExprToType(lex.take(), UseType, CK_DerivedToBase, VK, &BasePath); + LHS = ImpCastExprToType(LHS.take(), UseType, CK_DerivedToBase, VK, + &BasePath); } - if (isa<CXXScalarValueInitExpr>(rex.get()->IgnoreParens())) { + if (isa<CXXScalarValueInitExpr>(RHS.get()->IgnoreParens())) { // Diagnose use of pointer-to-member type which when used as // the functional cast in a pointer-to-member expression. Diag(Loc, diag::err_pointer_to_member_type) << isIndirect; @@ -3334,7 +3372,7 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &lex, ExprResult &rex, // The cv qualifiers are the union of those in the pointer and the left side, // in accordance with 5.5p5 and 5.2.5. QualType Result = MemPtr->getPointeeType(); - Result = Context.getCVRQualifiedType(Result, LType.getCVRQualifiers()); + Result = Context.getCVRQualifiedType(Result, LHSType.getCVRQualifiers()); // C++0x [expr.mptr.oper]p6: // In a .* expression whose object expression is an rvalue, the program is @@ -3349,15 +3387,15 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &lex, ExprResult &rex, break; case RQ_LValue: - if (!isIndirect && !lex.get()->Classify(Context).isLValue()) + if (!isIndirect && !LHS.get()->Classify(Context).isLValue()) Diag(Loc, diag::err_pointer_to_member_oper_value_classify) - << RType << 1 << lex.get()->getSourceRange(); + << RHSType << 1 << LHS.get()->getSourceRange(); break; case RQ_RValue: - if (isIndirect || !lex.get()->Classify(Context).isRValue()) + if (isIndirect || !LHS.get()->Classify(Context).isRValue()) Diag(Loc, diag::err_pointer_to_member_oper_value_classify) - << RType << 0 << lex.get()->getSourceRange(); + << RHSType << 0 << LHS.get()->getSourceRange(); break; } } @@ -3375,7 +3413,7 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &lex, ExprResult &rex, } else if (isIndirect) { VK = VK_LValue; } else { - VK = lex.get()->getValueKind(); + VK = LHS.get()->getValueKind(); } return Result; @@ -3528,8 +3566,7 @@ static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS break; case OR_Deleted: - assert(false && "Conditional operator has only built-in overloads"); - break; + llvm_unreachable("Conditional operator has only built-in overloads"); } return true; } @@ -3838,9 +3875,9 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, // conversions in both directions. If only one works, or if the two composite // types are the same, we have succeeded. // FIXME: extended qualifiers? - typedef llvm::SmallVector<unsigned, 4> QualifierVector; + typedef SmallVector<unsigned, 4> QualifierVector; QualifierVector QualifierUnion; - typedef llvm::SmallVector<std::pair<const Type *, const Type *>, 4> + typedef SmallVector<std::pair<const Type *, const Type *>, 4> ContainingClassVector; ContainingClassVector MemberOfClass; QualType Composite1 = Context.getCanonicalType(T1), @@ -4044,27 +4081,30 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { // actual method. FIXME: we should infer retention by selector in // cases where we don't have an actual method. } else { - Decl *D = 0; + ObjCMethodDecl *D = 0; if (ObjCMessageExpr *Send = dyn_cast<ObjCMessageExpr>(E)) { D = Send->getMethodDecl(); } else { CastExpr *CE = cast<CastExpr>(E); - // FIXME. What other cast kinds to check for? - if (CE->getCastKind() == CK_ObjCProduceObject || - CE->getCastKind() == CK_LValueToRValue) - return MaybeBindToTemporary(CE->getSubExpr()); assert(CE->getCastKind() == CK_GetObjCProperty); const ObjCPropertyRefExpr *PRE = CE->getSubExpr()->getObjCProperty(); D = (PRE->isImplicitProperty() ? PRE->getImplicitPropertyGetter() : 0); } ReturnsRetained = (D && D->hasAttr<NSReturnsRetainedAttr>()); + + // Don't do reclaims on performSelector calls; despite their + // return type, the invoked method doesn't necessarily actually + // return an object. + if (!ReturnsRetained && + D && D->getMethodFamily() == OMF_performSelector) + return Owned(E); } ExprNeedsCleanups = true; - CastKind ck = (ReturnsRetained ? CK_ObjCConsumeObject - : CK_ObjCReclaimReturnedObject); + CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject + : CK_ARCReclaimReturnedObject); return Owned(ImplicitCastExpr::Create(Context, E->getType(), ck, E, 0, VK_RValue)); } @@ -4172,7 +4212,7 @@ Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, if (OpKind == tok::arrow) { // The set of types we've considered so far. llvm::SmallPtrSet<CanQualType,8> CTypes; - llvm::SmallVector<SourceLocation, 8> Locations; + SmallVector<SourceLocation, 8> Locations; CTypes.insert(Context.getCanonicalType(BaseType)); while (BaseType->isRecordType()) { @@ -4509,7 +4549,8 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, } ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, - CXXMethodDecl *Method) { + CXXMethodDecl *Method, + bool HadMultipleCandidates) { ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/0, FoundDecl, Method); if (Exp.isInvalid()) @@ -4519,6 +4560,9 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, new (Context) MemberExpr(Exp.take(), /*IsArrow=*/false, Method, SourceLocation(), Method->getType(), VK_RValue, OK_Ordinary); + if (HadMultipleCandidates) + ME->setHadMultipleCandidates(true); + QualType ResultType = Method->getResultType(); ExprValueKind VK = Expr::getValueKindForType(ResultType); ResultType = ResultType.getNonLValueExprType(Context); @@ -4608,7 +4652,7 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE) { if (FullExpr.isInvalid()) return ExprError(); - CheckImplicitConversions(FullExpr.get()); + CheckImplicitConversions(FullExpr.get(), FullExpr.get()->getExprLoc()); return MaybeCreateExprWithCleanups(FullExpr); } |