From e11f410f5c8b0655b527e4d4160c5e4cecace4da Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 18 Dec 2015 21:45:41 +0000 Subject: [PATCH] Wire a SourceLocation into IsDerivedFrom and move the RequireCompleteType call for the derived class into it. This is mostly just a cleanup, but could in principle be a bugfix if there is some codepath that reaches here and didn't previously require a complete type (I couldn't find any such codepath, though). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@256037 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Sema.h | 5 +- lib/Sema/SemaCast.cpp | 17 ++-- lib/Sema/SemaDeclCXX.cpp | 29 ++++--- lib/Sema/SemaExceptionSpec.cpp | 2 +- lib/Sema/SemaExpr.cpp | 7 +- lib/Sema/SemaExprCXX.cpp | 8 +- lib/Sema/SemaFixItUtils.cpp | 2 +- lib/Sema/SemaInit.cpp | 9 ++- lib/Sema/SemaOverload.cpp | 120 +++++++++++++++-------------- lib/Sema/SemaTemplateDeduction.cpp | 2 +- 10 files changed, 108 insertions(+), 93 deletions(-) diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index ae079b2417..682f0d25c1 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5370,8 +5370,9 @@ public: void ActOnBaseSpecifiers(Decl *ClassDecl, CXXBaseSpecifier **Bases, unsigned NumBases); - bool IsDerivedFrom(QualType Derived, QualType Base); - bool IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths); + bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base); + bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base, + CXXBasePaths &Paths); // FIXME: I don't like this name. void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath); diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index 4aecd08d9f..1cc97fcd9d 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -683,7 +683,8 @@ void CastOperation::CheckDynamicCast() { // C++ 5.2.7p5 // Upcasts are resolved statically. - if (DestRecord && Self.IsDerivedFrom(SrcPointee, DestPointee)) { + if (DestRecord && + Self.IsDerivedFrom(OpRange.getBegin(), SrcPointee, DestPointee)) { if (Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee, OpRange.getBegin(), OpRange, &BasePath)) { @@ -1171,7 +1172,8 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType, Kind = CK_DerivedToBase; CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/true); - if (!Self.IsDerivedFrom(SrcExpr->getType(), R->getPointeeType(), Paths)) + if (!Self.IsDerivedFrom(SrcExpr->getLocStart(), SrcExpr->getType(), + R->getPointeeType(), Paths)) return TC_NotApplicable; Self.BuildBasePathArray(Paths, BasePath); @@ -1271,7 +1273,7 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/true); - if (!Self.IsDerivedFrom(DestType, SrcType, Paths)) { + if (!Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths)) { return TC_NotApplicable; } @@ -1307,7 +1309,7 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, if (!Paths.isRecordingPaths()) { Paths.clear(); Paths.setRecordingPaths(true); - Self.IsDerivedFrom(DestType, SrcType, Paths); + Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths); } std::string PathDisplayStr; std::set DisplayedPaths; @@ -1410,16 +1412,15 @@ TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType, QualType DestClass(DestMemPtr->getClass(), 0); CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/true); - if (Self.RequireCompleteType(OpRange.getBegin(), SrcClass, 0) || - !Self.IsDerivedFrom(SrcClass, DestClass, Paths)) { + if (!Self.IsDerivedFrom(OpRange.getBegin(), SrcClass, DestClass, Paths)) return TC_NotApplicable; - } // B is a base of D. But is it an allowed base? If not, it's a hard error. if (Paths.isAmbiguous(Self.Context.getCanonicalType(DestClass))) { Paths.clear(); Paths.setRecordingPaths(true); - bool StillOkay = Self.IsDerivedFrom(SrcClass, DestClass, Paths); + bool StillOkay = + Self.IsDerivedFrom(OpRange.getBegin(), SrcClass, DestClass, Paths); assert(StillOkay); (void)StillOkay; std::string PathDisplayStr = Self.getAmbiguousPathsDisplayString(Paths); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index b0b362f4cd..2cc0d071a9 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1665,14 +1665,19 @@ void Sema::ActOnBaseSpecifiers(Decl *ClassDecl, CXXBaseSpecifier **Bases, /// \brief Determine whether the type \p Derived is a C++ class that is /// derived from the type \p Base. -bool Sema::IsDerivedFrom(QualType Derived, QualType Base) { +bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base) { if (!getLangOpts().CPlusPlus) return false; - + CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl(); if (!DerivedRD) return false; + // FIXME: In a modules build, do we need the entire path to be visible for us + // to be able to use the inheritance relationship? + if (RequireCompleteType(Loc, Derived, 0) && !DerivedRD->isBeingDefined()) + return false; + CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl(); if (!BaseRD) return false; @@ -1682,13 +1687,13 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base) { if (BaseRD->isInvalidDecl() || DerivedRD->isInvalidDecl()) return false; - // FIXME: instantiate DerivedRD if necessary. We need a PoI for this. - return DerivedRD->hasDefinition() && DerivedRD->isDerivedFrom(BaseRD); + return DerivedRD->isDerivedFrom(BaseRD); } /// \brief Determine whether the type \p Derived is a C++ class that is /// derived from the type \p Base. -bool Sema::IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths) { +bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base, + CXXBasePaths &Paths) { if (!getLangOpts().CPlusPlus) return false; @@ -1696,6 +1701,9 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths) { if (!DerivedRD) return false; + if (RequireCompleteType(Loc, Derived, 0) && !DerivedRD->isBeingDefined()) + return false; + CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl(); if (!BaseRD) return false; @@ -1747,7 +1755,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, // explore multiple paths to determine if there is an ambiguity. CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/false); - bool DerivationOkay = IsDerivedFrom(Derived, Base, Paths); + bool DerivationOkay = IsDerivedFrom(Loc, Derived, Base, Paths); assert(DerivationOkay && "Can only be used with a derived-to-base conversion"); (void)DerivationOkay; @@ -1781,7 +1789,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, // performance isn't as much of an issue. Paths.clear(); Paths.setRecordingPaths(true); - bool StillOkay = IsDerivedFrom(Derived, Base, Paths); + bool StillOkay = IsDerivedFrom(Loc, Derived, Base, Paths); assert(StillOkay && "Can only be used with a derived-to-base conversion"); (void)StillOkay; @@ -2757,7 +2765,8 @@ static bool FindBaseInitializer(Sema &SemaRef, // virtual base class. CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/false); - if (SemaRef.IsDerivedFrom(SemaRef.Context.getTypeDeclType(ClassDecl), + if (SemaRef.IsDerivedFrom(ClassDecl->getLocation(), + SemaRef.Context.getTypeDeclType(ClassDecl), BaseType, Paths)) { for (CXXBasePaths::paths_iterator Path = Paths.begin(); Path != Paths.end(); ++Path) { @@ -7123,7 +7132,7 @@ Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) { if (ConvType == ClassType) Diag(Conversion->getLocation(), diag::warn_conv_to_self_not_used) << ClassType; - else if (IsDerivedFrom(ClassType, ConvType)) + else if (IsDerivedFrom(Conversion->getLocation(), ClassType, ConvType)) Diag(Conversion->getLocation(), diag::warn_conv_to_base_not_used) << ClassType << ConvType; } else if (ConvType->isVoidType()) { @@ -13021,7 +13030,7 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New, if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) { // Check if the new class derives from the old class. - if (!IsDerivedFrom(NewClassTy, OldClassTy)) { + if (!IsDerivedFrom(New->getLocation(), NewClassTy, OldClassTy)) { Diag(New->getLocation(), diag::err_covariant_return_not_derived) << New->getDeclName() << NewTy << OldTy << New->getReturnTypeSourceRange(); diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp index 9f95e4b606..f12bf2415d 100644 --- a/lib/Sema/SemaExceptionSpec.cpp +++ b/lib/Sema/SemaExceptionSpec.cpp @@ -713,7 +713,7 @@ bool Sema::CheckExceptionSpecSubset( continue; Paths.clear(); - if (!IsDerivedFrom(CanonicalSubT, CanonicalSuperT, Paths)) + if (!IsDerivedFrom(SubLoc, CanonicalSubT, CanonicalSuperT, Paths)) continue; if (Paths.isAmbiguous(Context.getCanonicalType(CanonicalSuperT))) diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index b8cb50c9ae..d31a816b80 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2595,7 +2595,7 @@ Sema::PerformObjectMemberConversion(Expr *From, // In C++98, the qualifier type doesn't actually have to be a base // type of the object type, in which case we just ignore it. // Otherwise build the appropriate casts. - if (IsDerivedFrom(FromRecordType, QRecordType)) { + if (IsDerivedFrom(FromLoc, FromRecordType, QRecordType)) { CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, QRecordType, FromLoc, FromRange, &BasePath)) @@ -2631,7 +2631,7 @@ Sema::PerformObjectMemberConversion(Expr *From, // We only need to do this if the naming-class to declaring-class // conversion is non-trivial. if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) { - assert(IsDerivedFrom(FromRecordType, URecordType)); + assert(IsDerivedFrom(FromLoc, FromRecordType, URecordType)); CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, URecordType, FromLoc, FromRange, &BasePath)) @@ -11313,7 +11313,8 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, // If the member was found in a base class, introduce OffsetOfNodes for // the base class indirections. CXXBasePaths Paths; - if (IsDerivedFrom(CurrentType, Context.getTypeDeclType(Parent), Paths)) { + if (IsDerivedFrom(OC.LocStart, CurrentType, Context.getTypeDeclType(Parent), + Paths)) { if (Paths.getDetectedVirtual()) { Diag(OC.LocEnd, diag::err_offsetof_field_of_virtual_base) << MemberDecl->getDeclName() diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index e5df6c1bf3..1604a70d52 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4578,7 +4578,7 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, return QualType(); } - if (!IsDerivedFrom(LHSType, Class)) { + if (!IsDerivedFrom(Loc, LHSType, Class)) { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling << (int)isIndirect << LHS.get()->getType(); return QualType(); @@ -4706,9 +4706,9 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, const RecordType *FRec = FTy->getAs(); const RecordType *TRec = TTy->getAs(); bool FDerivedFromT = FRec && TRec && FRec != TRec && - Self.IsDerivedFrom(FTy, TTy); - if (FRec && TRec && - (FRec == TRec || FDerivedFromT || Self.IsDerivedFrom(TTy, FTy))) { + Self.IsDerivedFrom(QuestionLoc, FTy, TTy); + if (FRec && TRec && (FRec == TRec || FDerivedFromT || + Self.IsDerivedFrom(QuestionLoc, TTy, FTy))) { // E1 can be converted to match E2 if the class of T2 is the // same type as, or a base class of, the class of T1, and // [cv2 > cv1]. diff --git a/lib/Sema/SemaFixItUtils.cpp b/lib/Sema/SemaFixItUtils.cpp index 982d9cf4c2..714fbedf09 100644 --- a/lib/Sema/SemaFixItUtils.cpp +++ b/lib/Sema/SemaFixItUtils.cpp @@ -42,7 +42,7 @@ bool ConversionFixItGenerator::compareTypesSimple(CanQualType From, const CanQualType FromUnq = From.getUnqualifiedType(); const CanQualType ToUnq = To.getUnqualifiedType(); - if ((FromUnq == ToUnq || (S.IsDerivedFrom(FromUnq, ToUnq)) ) && + if ((FromUnq == ToUnq || (S.IsDerivedFrom(Loc, FromUnq, ToUnq)) ) && To.isAtLeastAsQualifiedAs(From)) return true; return false; diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index ba1f140a9e..1f0504fd38 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -3699,7 +3699,7 @@ static void TryListInitialization(Sema &S, if (DestType->isRecordType()) { QualType InitType = InitList->getInit(0)->getType(); if (S.Context.hasSameUnqualifiedType(InitType, DestType) || - S.IsDerivedFrom(InitType, DestType)) { + S.IsDerivedFrom(InitList->getLocStart(), InitType, DestType)) { Expr *InitAsExpr = InitList->getInit(0); TryConstructorInitialization(S, Entity, Kind, InitAsExpr, DestType, Sequence, /*InitListSyntax*/ false, @@ -5007,7 +5007,7 @@ void InitializationSequence::InitializeFrom(Sema &S, if (Kind.getKind() == InitializationKind::IK_Direct || (Kind.getKind() == InitializationKind::IK_Copy && (Context.hasSameUnqualifiedType(SourceType, DestType) || - S.IsDerivedFrom(SourceType, DestType)))) + S.IsDerivedFrom(Initializer->getLocStart(), SourceType, DestType)))) TryConstructorInitialization(S, Entity, Kind, Args, DestType, *this); // - Otherwise (i.e., for the remaining copy-initialization cases), @@ -5036,7 +5036,8 @@ void InitializationSequence::InitializeFrom(Sema &S, bool NeedAtomicConversion = false; if (const AtomicType *Atomic = DestType->getAs()) { if (Context.hasSameUnqualifiedType(SourceType, Atomic->getValueType()) || - S.IsDerivedFrom(SourceType, Atomic->getValueType())) { + S.IsDerivedFrom(Initializer->getLocStart(), SourceType, + Atomic->getValueType())) { DestType = Atomic->getValueType(); NeedAtomicConversion = true; } @@ -6378,7 +6379,7 @@ InitializationSequence::Perform(Sema &S, CastKind = CK_ConstructorConversion; QualType Class = S.Context.getTypeDeclType(Constructor->getParent()); if (S.Context.hasSameUnqualifiedType(SourceType, Class) || - S.IsDerivedFrom(SourceType, Class)) + S.IsDerivedFrom(Loc, SourceType, Class)) IsCopy = true; CreatedObject = true; diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 1da448abed..a0fb1ea3db 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -89,7 +89,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, static ImplicitConversionSequence::CompareKind -CompareStandardConversionSequences(Sema &S, +CompareStandardConversionSequences(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2); @@ -99,7 +99,7 @@ CompareQualificationConversions(Sema &S, const StandardConversionSequence& SCS2); static ImplicitConversionSequence::CompareKind -CompareDerivedToBaseConversions(Sema &S, +CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2); @@ -1164,7 +1164,8 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType, QualType ToCanon = S.Context.getCanonicalType(ToType).getUnqualifiedType(); if (Constructor->isCopyConstructor() && - (FromCanon == ToCanon || S.IsDerivedFrom(FromCanon, ToCanon))) { + (FromCanon == ToCanon || + S.IsDerivedFrom(From->getLocStart(), FromCanon, ToCanon))) { // Turn this into a "standard" conversion sequence, so that it // gets ranked with standard conversion sequences. ICS.setStandard(); @@ -1254,7 +1255,7 @@ TryImplicitConversion(Sema &S, Expr *From, QualType ToType, QualType FromType = From->getType(); if (ToType->getAs() && FromType->getAs() && (S.Context.hasSameUnqualifiedType(FromType, ToType) || - S.IsDerivedFrom(FromType, ToType))) { + S.IsDerivedFrom(From->getLocStart(), FromType, ToType))) { ICS.setStandard(); ICS.Standard.setAsIdentityConversion(); ICS.Standard.setFromType(FromType); @@ -2152,8 +2153,7 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType, if (getLangOpts().CPlusPlus && FromPointeeType->isRecordType() && ToPointeeType->isRecordType() && !Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType) && - !RequireCompleteType(From->getLocStart(), FromPointeeType, 0) && - IsDerivedFrom(FromPointeeType, ToPointeeType)) { + IsDerivedFrom(From->getLocStart(), FromPointeeType, ToPointeeType)) { ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr, ToPointeeType, ToType, Context); @@ -2759,8 +2759,7 @@ bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToClass(ToTypePtr->getClass(), 0); if (!Context.hasSameUnqualifiedType(FromClass, ToClass) && - !RequireCompleteType(From->getLocStart(), ToClass, 0) && - IsDerivedFrom(ToClass, FromClass)) { + IsDerivedFrom(From->getLocStart(), ToClass, FromClass)) { ConvertedType = Context.getMemberPointerType(FromTypePtr->getPointeeType(), ToClass.getTypePtr()); return true; @@ -2803,7 +2802,8 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType, CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, /*DetectVirtual=*/true); - bool DerivationOkay = IsDerivedFrom(ToClass, FromClass, Paths); + bool DerivationOkay = + IsDerivedFrom(From->getLocStart(), ToClass, FromClass, Paths); assert(DerivationOkay && "Should not have been called if derivation isn't OK."); (void)DerivationOkay; @@ -3082,7 +3082,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, // the parentheses of the initializer. if (S.Context.hasSameUnqualifiedType(ToType, From->getType()) || (From->getType()->getAs() && - S.IsDerivedFrom(From->getType(), ToType))) + S.IsDerivedFrom(From->getLocStart(), From->getType(), ToType))) ConstructorsOnly = true; S.RequireCompleteType(From->getExprLoc(), ToType, 0); @@ -3342,7 +3342,7 @@ static bool hasDeprecatedStringLiteralToCharPtrConversion( /// conversion sequences to determine whether one is better than the /// other or if they are indistinguishable (C++ 13.3.3.2). static ImplicitConversionSequence::CompareKind -CompareImplicitConversionSequences(Sema &S, +CompareImplicitConversionSequences(Sema &S, SourceLocation Loc, const ImplicitConversionSequence& ICS1, const ImplicitConversionSequence& ICS2) { @@ -3422,7 +3422,7 @@ CompareImplicitConversionSequences(Sema &S, if (ICS1.isStandard()) // Standard conversion sequence S1 is a better conversion sequence than // standard conversion sequence S2 if [...] - Result = CompareStandardConversionSequences(S, + Result = CompareStandardConversionSequences(S, Loc, ICS1.Standard, ICS2.Standard); else if (ICS1.isUserDefined()) { // User-defined conversion sequence U1 is a better conversion @@ -3433,7 +3433,7 @@ CompareImplicitConversionSequences(Sema &S, // U2 (C++ 13.3.3.2p3). if (ICS1.UserDefined.ConversionFunction == ICS2.UserDefined.ConversionFunction) - Result = CompareStandardConversionSequences(S, + Result = CompareStandardConversionSequences(S, Loc, ICS1.UserDefined.After, ICS2.UserDefined.After); else @@ -3531,7 +3531,7 @@ isBetterReferenceBindingKind(const StandardConversionSequence &SCS1, /// conversion sequences to determine whether one is better than the /// other or if they are indistinguishable (C++ 13.3.3.2p3). static ImplicitConversionSequence::CompareKind -CompareStandardConversionSequences(Sema &S, +CompareStandardConversionSequences(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2) { @@ -3587,7 +3587,7 @@ CompareStandardConversionSequences(Sema &S, // Neither conversion sequence converts to a void pointer; compare // their derived-to-base conversions. if (ImplicitConversionSequence::CompareKind DerivedCK - = CompareDerivedToBaseConversions(S, SCS1, SCS2)) + = CompareDerivedToBaseConversions(S, Loc, SCS1, SCS2)) return DerivedCK; } else if (SCS1ConvertsToVoid && SCS2ConvertsToVoid && !S.Context.hasSameType(SCS1.getFromType(), SCS2.getFromType())) { @@ -3607,9 +3607,9 @@ CompareStandardConversionSequences(Sema &S, QualType FromPointee1 = FromType1->getPointeeType().getUnqualifiedType(); QualType FromPointee2 = FromType2->getPointeeType().getUnqualifiedType(); - if (S.IsDerivedFrom(FromPointee2, FromPointee1)) + if (S.IsDerivedFrom(Loc, FromPointee2, FromPointee1)) return ImplicitConversionSequence::Better; - else if (S.IsDerivedFrom(FromPointee1, FromPointee2)) + else if (S.IsDerivedFrom(Loc, FromPointee1, FromPointee2)) return ImplicitConversionSequence::Worse; // Objective-C++: If one interface is more specific than the @@ -3817,7 +3817,7 @@ CompareQualificationConversions(Sema &S, /// [over.ics.rank]p4b3). As part of these checks, we also look at /// conversions between Objective-C interface types. static ImplicitConversionSequence::CompareKind -CompareDerivedToBaseConversions(Sema &S, +CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc, const StandardConversionSequence& SCS1, const StandardConversionSequence& SCS2) { QualType FromType1 = SCS1.getFromType(); @@ -3860,17 +3860,17 @@ CompareDerivedToBaseConversions(Sema &S, // -- conversion of C* to B* is better than conversion of C* to A*, if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) { - if (S.IsDerivedFrom(ToPointee1, ToPointee2)) + if (S.IsDerivedFrom(Loc, ToPointee1, ToPointee2)) return ImplicitConversionSequence::Better; - else if (S.IsDerivedFrom(ToPointee2, ToPointee1)) + else if (S.IsDerivedFrom(Loc, ToPointee2, ToPointee1)) return ImplicitConversionSequence::Worse; } // -- conversion of B* to A* is better than conversion of C* to A*, if (FromPointee1 != FromPointee2 && ToPointee1 == ToPointee2) { - if (S.IsDerivedFrom(FromPointee2, FromPointee1)) + if (S.IsDerivedFrom(Loc, FromPointee2, FromPointee1)) return ImplicitConversionSequence::Better; - else if (S.IsDerivedFrom(FromPointee1, FromPointee2)) + else if (S.IsDerivedFrom(Loc, FromPointee1, FromPointee2)) return ImplicitConversionSequence::Worse; } } else if (SCS1.Second == ICK_Pointer_Conversion && @@ -3967,16 +3967,16 @@ CompareDerivedToBaseConversions(Sema &S, QualType ToPointee2 = QualType(ToPointeeType2, 0).getUnqualifiedType(); // conversion of A::* to B::* is better than conversion of A::* to C::*, if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) { - if (S.IsDerivedFrom(ToPointee1, ToPointee2)) + if (S.IsDerivedFrom(Loc, ToPointee1, ToPointee2)) return ImplicitConversionSequence::Worse; - else if (S.IsDerivedFrom(ToPointee2, ToPointee1)) + else if (S.IsDerivedFrom(Loc, ToPointee2, ToPointee1)) return ImplicitConversionSequence::Better; } // conversion of B::* to C::* is better than conversion of A::* to C::* if (ToPointee1 == ToPointee2 && FromPointee1 != FromPointee2) { - if (S.IsDerivedFrom(FromPointee1, FromPointee2)) + if (S.IsDerivedFrom(Loc, FromPointee1, FromPointee2)) return ImplicitConversionSequence::Better; - else if (S.IsDerivedFrom(FromPointee2, FromPointee1)) + else if (S.IsDerivedFrom(Loc, FromPointee2, FromPointee1)) return ImplicitConversionSequence::Worse; } } @@ -3988,9 +3988,9 @@ CompareDerivedToBaseConversions(Sema &S, // reference of type A&, if (S.Context.hasSameUnqualifiedType(FromType1, FromType2) && !S.Context.hasSameUnqualifiedType(ToType1, ToType2)) { - if (S.IsDerivedFrom(ToType1, ToType2)) + if (S.IsDerivedFrom(Loc, ToType1, ToType2)) return ImplicitConversionSequence::Better; - else if (S.IsDerivedFrom(ToType2, ToType1)) + else if (S.IsDerivedFrom(Loc, ToType2, ToType1)) return ImplicitConversionSequence::Worse; } @@ -4000,9 +4000,9 @@ CompareDerivedToBaseConversions(Sema &S, // reference of type A&, if (!S.Context.hasSameUnqualifiedType(FromType1, FromType2) && S.Context.hasSameUnqualifiedType(ToType1, ToType2)) { - if (S.IsDerivedFrom(FromType2, FromType1)) + if (S.IsDerivedFrom(Loc, FromType2, FromType1)) return ImplicitConversionSequence::Better; - else if (S.IsDerivedFrom(FromType1, FromType2)) + else if (S.IsDerivedFrom(Loc, FromType1, FromType2)) return ImplicitConversionSequence::Worse; } } @@ -4053,7 +4053,7 @@ Sema::CompareReferenceRelationship(SourceLocation Loc, // Nothing to do. } else if (!RequireCompleteType(Loc, OrigT2, 0) && isTypeValid(UnqualT1) && isTypeValid(UnqualT2) && - IsDerivedFrom(UnqualT2, UnqualT1)) + IsDerivedFrom(Loc, UnqualT2, UnqualT1)) DerivedToBase = true; else if (UnqualT1->isObjCObjectOrInterfaceType() && UnqualT2->isObjCObjectOrInterfaceType() && @@ -4536,7 +4536,7 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType, if (ToType->isRecordType()) { QualType InitType = From->getInit(0)->getType(); if (S.Context.hasSameUnqualifiedType(InitType, ToType) || - S.IsDerivedFrom(InitType, ToType)) + S.IsDerivedFrom(From->getLocStart(), InitType, ToType)) return TryCopyInitialization(S, From->getInit(0), ToType, SuppressUserConversions, InOverloadResolution, @@ -4593,7 +4593,8 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType, } // Otherwise, look for the worst conversion. if (Result.isBad() || - CompareImplicitConversionSequences(S, ICS, Result) == + CompareImplicitConversionSequences(S, From->getLocStart(), ICS, + Result) == ImplicitConversionSequence::Worse) Result = ICS; } @@ -4800,7 +4801,7 @@ static bool TryCopyInitialization(const CanQualType FromQTy, /// parameter of the given member function (@c Method) from the /// expression @p From. static ImplicitConversionSequence -TryObjectArgumentInitialization(Sema &S, QualType FromType, +TryObjectArgumentInitialization(Sema &S, SourceLocation Loc, QualType FromType, Expr::Classification FromClassification, CXXMethodDecl *Method, CXXRecordDecl *ActingContext) { @@ -4860,7 +4861,7 @@ TryObjectArgumentInitialization(Sema &S, QualType FromType, ImplicitConversionKind SecondKind; if (ClassTypeCanon == FromTypeCanon.getLocalUnqualifiedType()) { SecondKind = ICK_Identity; - } else if (S.IsDerivedFrom(FromType, ClassType)) + } else if (S.IsDerivedFrom(Loc, FromType, ClassType)) SecondKind = ICK_Derived_To_Base; else { ICS.setBad(BadConversionSequence::unrelated_class, @@ -4935,7 +4936,8 @@ Sema::PerformObjectArgumentInitialization(Expr *From, // Note that we always use the true parent context when performing // the actual argument initialization. ImplicitConversionSequence ICS = TryObjectArgumentInitialization( - *this, From->getType(), FromClassification, Method, Method->getParent()); + *this, From->getLocStart(), From->getType(), FromClassification, Method, + Method->getParent()); if (ICS.isBad()) { if (ICS.Bad.Kind == BadConversionSequence::bad_qualifiers) { Qualifiers FromQs = FromRecordType.getQualifiers(); @@ -5716,10 +5718,10 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, // A member function template is never instantiated to perform the copy // of a class object to an object of its class type. QualType ClassType = Context.getTypeDeclType(Constructor->getParent()); - if (Args.size() == 1 && - Constructor->isSpecializationCopyingObject() && + if (Args.size() == 1 && Constructor->isSpecializationCopyingObject() && (Context.hasSameUnqualifiedType(ClassType, Args[0]->getType()) || - IsDerivedFrom(Args[0]->getType(), ClassType))) { + IsDerivedFrom(Args[0]->getLocStart(), Args[0]->getType(), + ClassType))) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_illegal_constructor; return; @@ -6136,9 +6138,9 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, else { // Determine the implicit conversion sequence for the object // parameter. - Candidate.Conversions[0] - = TryObjectArgumentInitialization(*this, ObjectType, ObjectClassification, - Method, ActingContext); + Candidate.Conversions[0] = TryObjectArgumentInitialization( + *this, CandidateSet.getLocation(), ObjectType, ObjectClassification, + Method, ActingContext); if (Candidate.Conversions[0].isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; @@ -6395,10 +6397,9 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, CXXRecordDecl *ConversionContext = cast(ImplicitParamType->getAs()->getDecl()); - Candidate.Conversions[0] - = TryObjectArgumentInitialization(*this, From->getType(), - From->Classify(Context), - Conversion, ConversionContext); + Candidate.Conversions[0] = TryObjectArgumentInitialization( + *this, CandidateSet.getLocation(), From->getType(), + From->Classify(Context), Conversion, ConversionContext); if (Candidate.Conversions[0].isBad()) { Candidate.Viable = false; @@ -6412,7 +6413,8 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, QualType FromCanon = Context.getCanonicalType(From->getType().getUnqualifiedType()); QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType(); - if (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon)) { + if (FromCanon == ToCanon || + IsDerivedFrom(CandidateSet.getLocation(), FromCanon, ToCanon)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_trivial_conversion; return; @@ -6572,10 +6574,9 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, // Determine the implicit conversion sequence for the implicit // object parameter. - ImplicitConversionSequence ObjectInit - = TryObjectArgumentInitialization(*this, Object->getType(), - Object->Classify(Context), - Conversion, ActingContext); + ImplicitConversionSequence ObjectInit = TryObjectArgumentInitialization( + *this, CandidateSet.getLocation(), Object->getType(), + Object->Classify(Context), Conversion, ActingContext); if (ObjectInit.isBad()) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_conversion; @@ -8122,7 +8123,7 @@ public: const MemberPointerType *mptr = cast(*MemPtr); QualType C2 = QualType(mptr->getClass(), 0); C2 = C2.getUnqualifiedType(); - if (C1 != C2 && !S.IsDerivedFrom(C1, C2)) + if (C1 != C2 && !S.IsDerivedFrom(CandidateSet.getLocation(), C1, C2)) break; QualType ParamTypes[2] = { *Ptr, *MemPtr }; // build CV12 T& @@ -8508,7 +8509,7 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, assert(Cand2.NumConversions == NumArgs && "Overload candidate mismatch"); bool HasBetterConversion = false; for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) { - switch (CompareImplicitConversionSequences(S, + switch (CompareImplicitConversionSequences(S, Loc, Cand1.Conversions[ArgIdx], Cand2.Conversions[ArgIdx])) { case ImplicitConversionSequence::Better: @@ -8547,7 +8548,7 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, ImplicitConversionSequence::CompareKind Result = compareConversionFunctions(S, Cand1.Function, Cand2.Function); if (Result == ImplicitConversionSequence::Indistinguishable) - Result = CompareStandardConversionSequences(S, + Result = CompareStandardConversionSequences(S, Loc, Cand1.FinalConversion, Cand2.FinalConversion); @@ -9083,7 +9084,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, FromPtrTy->getPointeeType()) && !FromPtrTy->getPointeeType()->isIncompleteType() && !ToPtrTy->getPointeeType()->isIncompleteType() && - S.IsDerivedFrom(ToPtrTy->getPointeeType(), + S.IsDerivedFrom(SourceLocation(), ToPtrTy->getPointeeType(), FromPtrTy->getPointeeType())) BaseToDerivedConversion = 1; } @@ -9101,7 +9102,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, if (ToRefTy->getPointeeType().isAtLeastAsQualifiedAs(FromTy) && !FromTy->isIncompleteType() && !ToRefTy->getPointeeType()->isIncompleteType() && - S.IsDerivedFrom(ToRefTy->getPointeeType(), FromTy)) { + S.IsDerivedFrom(SourceLocation(), ToRefTy->getPointeeType(), FromTy)) { BaseToDerivedConversion = 3; } else if (ToTy->isLValueReferenceType() && !FromExpr->isLValue() && ToTy.getNonReferenceType().getCanonicalType() == @@ -9708,9 +9709,10 @@ static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) { namespace { struct CompareOverloadCandidatesForDisplay { Sema &S; + SourceLocation Loc; size_t NumArgs; - CompareOverloadCandidatesForDisplay(Sema &S, size_t nArgs) + CompareOverloadCandidatesForDisplay(Sema &S, SourceLocation Loc, size_t nArgs) : S(S), NumArgs(nArgs) {} bool operator()(const OverloadCandidate *L, @@ -9781,7 +9783,7 @@ struct CompareOverloadCandidatesForDisplay { int leftBetter = 0; unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument); for (unsigned E = L->NumConversions; I != E; ++I) { - switch (CompareImplicitConversionSequences(S, + switch (CompareImplicitConversionSequences(S, Loc, L->Conversions[I], R->Conversions[I])) { case ImplicitConversionSequence::Better: @@ -9936,7 +9938,7 @@ void OverloadCandidateSet::NoteCandidates(Sema &S, } std::sort(Cands.begin(), Cands.end(), - CompareOverloadCandidatesForDisplay(S, Args.size())); + CompareOverloadCandidatesForDisplay(S, OpLoc, Args.size())); bool ReportedAmbiguousConversions = false; diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 5a8360f4b2..66b9abc300 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -2738,7 +2738,7 @@ CheckOriginalCallArgDeduction(Sema &S, Sema::OriginalCallArg OriginalArg, return false; if (A->isRecordType() && isSimpleTemplateIdType(OriginalParamType) && - S.IsDerivedFrom(A, DeducedA)) + S.IsDerivedFrom(SourceLocation(), A, DeducedA)) return false; return true; -- 2.40.0