-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Revert "[clang] NFC: Clear some uses of MemberPointerType::getClass" #132281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revert "[clang] NFC: Clear some uses of MemberPointerType::getClass" #132281
Conversation
@llvm/pr-subscribers-clang-tidy @llvm/pr-subscribers-clang Author: Matheus Izvekov (mizvekov) ChangesReverts llvm/llvm-project#131965 Reverted due to issue reported here: #131965 (comment) Patch is 28.29 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/132281.diff 19 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
index a8a9e6bdcdff8..9d1d92b989bf1 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
@@ -70,7 +70,10 @@ void ComparePointerToMemberVirtualFunctionCheck::check(
// compare with variable which type is pointer to member function.
llvm::SmallVector<SourceLocation, 12U> SameSignatureVirtualMethods{};
const auto *MPT = cast<MemberPointerType>(DRE->getType().getCanonicalType());
- const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+ const Type *T = MPT->getClass();
+ if (T == nullptr)
+ return;
+ const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
if (RD == nullptr)
return;
diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
index b66cc8512fad6..0fea7946a59f9 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -219,8 +219,8 @@ bool isQualificationConvertiblePointer(QualType From, QualType To,
if (P1->isMemberPointerType())
return P2->isMemberPointerType() &&
- P1->getAs<MemberPointerType>()->getMostRecentCXXRecordDecl() ==
- P2->getAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
+ P1->getAs<MemberPointerType>()->getClass() ==
+ P2->getAs<MemberPointerType>()->getClass();
if (P1->isConstantArrayType())
return P2->isConstantArrayType() &&
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h
index 50d1ba1b8f63f..6699284d215bd 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -454,8 +454,6 @@ struct CanProxyAdaptor<MemberPointerType>
: public CanProxyBase<MemberPointerType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const CXXRecordDecl *,
- getMostRecentCXXRecordDecl)
};
// CanProxyAdaptors for arrays are intentionally unimplemented because
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 9724f0def743a..0befe615c4ee1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5769,11 +5769,10 @@ class Sema final : public SemaBase {
/// Determine whether the type \p Derived is a C++ class that is
/// derived from the type \p Base.
- bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
- CXXRecordDecl *Base, CXXBasePaths &Paths);
- bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
- CXXRecordDecl *Base);
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base);
+
+ /// Determine whether the type \p Derived is a C++ class that is
+ /// derived from the type \p Base.
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base,
CXXBasePaths &Paths);
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 9dc02b25f8495..91640c4eb5cf9 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -238,9 +238,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>();
const auto *ToMP = CE->getType()->getAs<MemberPointerType>();
- unsigned DerivedOffset =
- Ctx.collectBaseOffset(ToMP->getMostRecentCXXRecordDecl(),
- FromMP->getMostRecentCXXRecordDecl());
+ unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0),
+ QualType(FromMP->getClass(), 0));
if (!this->delegate(SubExpr))
return false;
@@ -254,9 +253,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>();
const auto *ToMP = CE->getType()->getAs<MemberPointerType>();
- unsigned DerivedOffset =
- Ctx.collectBaseOffset(FromMP->getMostRecentCXXRecordDecl(),
- ToMP->getMostRecentCXXRecordDecl());
+ unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0),
+ QualType(ToMP->getClass(), 0));
if (!this->delegate(SubExpr))
return false;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 92a28897cf3ee..0165a0a3b0df3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10551,9 +10551,8 @@ bool MemberPointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
if (!Result.castToDerived(Derived))
return Error(E);
}
- if (!Result.castToDerived(E->getType()
- ->castAs<MemberPointerType>()
- ->getMostRecentCXXRecordDecl()))
+ const Type *FinalTy = E->getType()->castAs<MemberPointerType>()->getClass();
+ if (!Result.castToDerived(FinalTy->getAsCXXRecordDecl()))
return Error(E);
return true;
}
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 15de407e122d8..fe34251688a98 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -695,7 +695,7 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
mangleQualifiers(MPT->getPointeeType().getQualifiers(), true);
// Member pointers are suffixed with a back reference to the member
// pointer's class name.
- mangleName(MPT->getMostRecentCXXRecordDecl());
+ mangleName(MPT->getClass()->getAsCXXRecordDecl());
} else
mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
} else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
@@ -3331,11 +3331,11 @@ void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,
manglePointerExtQualifiers(Quals, PointeeType);
if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
Out << '8';
- mangleName(T->getMostRecentCXXRecordDecl());
+ mangleName(T->getClass()->castAs<RecordType>()->getDecl());
mangleFunctionType(FPT, nullptr, true);
} else {
mangleQualifiers(PointeeType.getQualifiers(), true);
- mangleName(T->getMostRecentCXXRecordDecl());
+ mangleName(T->getClass()->castAs<RecordType>()->getDecl());
mangleType(PointeeType, Range, QMM_Drop);
}
}
@@ -4309,11 +4309,11 @@ void MicrosoftCXXNameMangler::mangleAutoReturnType(const MemberPointerType *T,
manglePointerExtQualifiers(Quals, PointeeType);
if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
Out << '8';
- mangleName(T->getMostRecentCXXRecordDecl());
+ mangleName(T->getClass()->castAs<RecordType>()->getDecl());
mangleFunctionType(FPT, nullptr, true);
} else {
mangleQualifiers(PointeeType.getQualifiers(), true);
- mangleName(T->getMostRecentCXXRecordDecl());
+ mangleName(T->getClass()->castAs<RecordType>()->getDecl());
mangleAutoReturnType(PointeeType, QMM_Drop);
}
}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 33e7008cc4776..72161c06a88d4 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2446,17 +2446,19 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
// Member pointers in the MS ABI have special behavior in
// RequireCompleteType: they attach a MSInheritanceAttr to the CXXRecordDecl
// to indicate which inheritance model to use.
- // The inheritance attribute might only be present on the most recent
- // CXXRecordDecl.
- const CXXRecordDecl *RD =
- cast<MemberPointerType>(CanonicalType)->getMostRecentCXXRecordDecl();
+ auto *MPTy = cast<MemberPointerType>(CanonicalType);
+ const Type *ClassTy = MPTy->getClass();
// Member pointers with dependent class types don't get special treatment.
- if (!RD)
+ if (ClassTy->isDependentType())
return false;
+ const CXXRecordDecl *RD = ClassTy->getAsCXXRecordDecl();
ASTContext &Context = RD->getASTContext();
// Member pointers not in the MS ABI don't get special treatment.
if (!Context.getTargetInfo().getCXXABI().isMicrosoft())
return false;
+ // The inheritance attribute might only be present on the most recent
+ // CXXRecordDecl, use that one.
+ RD = RD->getMostRecentNonInjectedDecl();
// Nothing interesting to do if the inheritance attribute is already set.
if (RD->hasAttr<MSInheritanceAttr>())
return false;
@@ -4711,8 +4713,7 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
return computeTypeLinkageInfo(cast<ReferenceType>(T)->getPointeeType());
case Type::MemberPointer: {
const auto *MPT = cast<MemberPointerType>(T);
- LinkageInfo LV =
- getDeclLinkageAndVisibility(MPT->getMostRecentCXXRecordDecl());
+ LinkageInfo LV = computeTypeLinkageInfo(MPT->getClass());
LV.merge(computeTypeLinkageInfo(MPT->getPointeeType()));
return LV;
}
@@ -5178,10 +5179,7 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {
}
CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
- auto *RD = getClass()->getAsCXXRecordDecl();
- if (!RD)
- return nullptr;
- return RD->getMostRecentNonInjectedDecl();
+ return getClass()->getAsCXXRecordDecl()->getMostRecentNonInjectedDecl();
}
void clang::FixedPointValueToString(SmallVectorImpl<char> &Str,
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index 2777c78d6459d..7c6dfc3e59d8c 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -50,7 +50,8 @@ CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer(
llvm::Value *MemPtr, const MemberPointerType *MPT) {
ErrorUnsupportedABI(CGF, "calls through member pointers");
- const auto *RD = MPT->getMostRecentCXXRecordDecl();
+ const auto *RD =
+ cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
ThisPtrForCall =
CGF.getAsNaturalPointerTo(This, CGF.getContext().getRecordType(RD));
const FunctionProtoType *FPT =
@@ -293,7 +294,7 @@ llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
derivedType = E->getType();
const CXXRecordDecl *derivedClass =
- derivedType->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
+ derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
return CGM.GetNonVirtualBaseClassOffset(derivedClass,
E->path_begin(),
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 98c93b5bb4883..fa69caa41936c 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -161,9 +161,10 @@ CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base,
QualType memberType = memberPtrType->getPointeeType();
CharUnits memberAlign =
CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo);
- memberAlign = CGM.getDynamicOffsetAlignment(
- base.getAlignment(), memberPtrType->getMostRecentCXXRecordDecl(),
- memberAlign);
+ memberAlign =
+ CGM.getDynamicOffsetAlignment(base.getAlignment(),
+ memberPtrType->getClass()->getAsCXXRecordDecl(),
+ memberAlign);
return Address(ptr, ConvertTypeForMem(memberPtrType->getPointeeType()),
memberAlign);
}
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index dcccbc0835d95..c462b02676813 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3490,8 +3490,7 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty,
}
}
- llvm::DIType *ClassType = getOrCreateType(
- QualType(Ty->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0), U);
+ llvm::DIType *ClassType = getOrCreateType(QualType(Ty->getClass(), 0), U);
if (Ty->isMemberDataPointerType())
return DBuilder.createMemberPointerType(
getOrCreateType(Ty->getPointeeType(), U), ClassType, Size, /*Align=*/0,
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 5d96959065dd9..f71c18a8041b1 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -453,7 +453,8 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
const auto *MPT = MemFnExpr->getType()->castAs<MemberPointerType>();
const auto *FPT = MPT->getPointeeType()->castAs<FunctionProtoType>();
- const auto *RD = MPT->getMostRecentCXXRecordDecl();
+ const auto *RD =
+ cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
// Emit the 'this' pointer.
Address This = Address::invalid();
@@ -462,9 +463,8 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
else
This = EmitLValue(BaseExpr, KnownNonNull).getAddress();
- EmitTypeCheck(
- TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this),
- QualType(MPT->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0));
+ EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this),
+ QualType(MPT->getClass(), 0));
// Get the member function pointer.
llvm::Value *MemFnPtr = EmitScalarExpr(MemFnExpr);
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index 11cf5758b6d3a..dfbd444a850a5 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -728,7 +728,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
case Type::MemberPointer: {
auto *MPTy = cast<MemberPointerType>(Ty);
if (!getCXXABI().isMemberPointerConvertible(MPTy)) {
- auto *C = MPTy->getMostRecentCXXRecordDecl()->getTypeForDecl();
+ auto *C = MPTy->getClass();
auto Insertion = RecordsWithOpaqueMemberPointers.insert({C, nullptr});
if (Insertion.second)
Insertion.first->second = llvm::StructType::create(getLLVMContext());
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index a5633f6349ffa..7e26a0da3d7d2 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -628,7 +628,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
const FunctionProtoType *FPT =
MPT->getPointeeType()->castAs<FunctionProtoType>();
- auto *RD = MPT->getMostRecentCXXRecordDecl();
+ auto *RD =
+ cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
@@ -797,7 +798,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
// Check the function pointer if CFI on member function pointers is enabled.
if (ShouldEmitCFICheck) {
- CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+ CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
if (RD->hasDefinition()) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
@@ -3798,8 +3799,7 @@ static bool ContainsIncompleteClassType(QualType Ty) {
if (const MemberPointerType *MemberPointerTy =
dyn_cast<MemberPointerType>(Ty)) {
// Check if the class type is incomplete.
- const auto *ClassType = cast<RecordType>(
- MemberPointerTy->getMostRecentCXXRecordDecl()->getTypeForDecl());
+ const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
if (IsIncompleteClassType(ClassType))
return true;
@@ -4538,8 +4538,7 @@ ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
// attributes of the type pointed to.
unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy);
- const auto *ClassType =
- cast<RecordType>(Ty->getMostRecentCXXRecordDecl()->getTypeForDecl());
+ const RecordType *ClassType = cast<RecordType>(Ty->getClass());
if (IsIncompleteClassType(ClassType))
Flags |= PTI_ContainingClassIncomplete;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 7b2e0df8cb55d..a1551e8027cd3 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -3069,46 +3069,48 @@ void Sema::ActOnBaseSpecifiers(Decl *ClassDecl,
AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl), Bases);
}
-bool Sema::IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
- CXXRecordDecl *Base, CXXBasePaths &Paths) {
+bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base) {
if (!getLangOpts().CPlusPlus)
return false;
- if (!Base || !Derived)
+ CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl();
+ if (!DerivedRD)
+ return false;
+
+ CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl();
+ if (!BaseRD)
return false;
// If either the base or the derived type is invalid, don't try to
// check whether one is derived from the other.
- if (Base->isInvalidDecl() || Derived->isInvalidDecl())
+ if (BaseRD->isInvalidDecl() || DerivedRD->isInvalidDecl())
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 (!isCompleteType(Loc, Context.getTypeDeclType(Derived)) &&
- !Derived->isBeingDefined())
+ if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined())
return false;
- return Derived->isDerivedFrom(Base, Paths);
-}
-
-bool Sema::IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
- CXXRecordDecl *Base) {
- CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
- /*DetectVirtual=*/false);
- return IsDerivedFrom(Loc, Derived, Base, Paths);
-}
-
-bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base) {
- CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
- /*DetectVirtual=*/false);
- return IsDerivedFrom(Loc, Derived->getAsCXXRecordDecl(),
- Base->getAsCXXRecordDecl(), Paths);
+ return DerivedRD->isDerivedFrom(BaseRD);
}
bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base,
CXXBasePaths &Paths) {
- return IsDerivedFrom(Loc, Derived->getAsCXXRecordDecl(),
- Base->getAsCXXRecordDecl(), Paths);
+ if (!getLangOpts().CPlusPlus)
+ return false;
+
+ CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl();
+ if (!DerivedRD)
+ return false;
+
+ CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl();
+ if (!BaseRD)
+ return false;
+
+ if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined())
+ return false;
+
+ return DerivedRD->isDerivedFrom(BaseRD, Paths);
}
static void BuildBasePathArray(const CXXBasePath &Path,
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 8f204b949cb2c..cbea98b8884e9 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6529,7 +6529,7 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
return QualType();
}
- CXXRecordDecl *RHSClass = MemPtr->getMostRecentCXXRecordDecl();
+ QualType Class(MemPtr->getClass(), 0);
// Note: C++ [expr.mptr.oper]p2-3 says that the class type into which the
// member pointer points must be completely-defined. However, there is no
@@ -6552,16 +6552,15 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
return QualType();
}
}
- CXXRecordDecl *LHSClass = LHSType->getAsCXXRecordDecl();
- if (!declaresSameEntity(LHSClass, RHSClass)) {
+ if (!Context.hasSameUnqualifiedType(Class, LHSType)) {
// If we want to check the hierarchy, we need a complete type.
if (RequireCompleteType(Loc, LHSType, diag::err_bad_memptr_lhs,
OpSpelling, (int)isIndirect)) {
return QualType();
}
- if (!IsDerivedF...
[truncated]
|
@llvm/pr-subscribers-clang-codegen Author: Matheus Izvekov (mizvekov) ChangesReverts llvm/llvm-project#131965 Reverted due to issue reported here: #131965 (comment) Patch is 28.29 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/132281.diff 19 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
index a8a9e6bdcdff8..9d1d92b989bf1 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
@@ -70,7 +70,10 @@ void ComparePointerToMemberVirtualFunctionCheck::check(
// compare with variable which type is pointer to member function.
llvm::SmallVector<SourceLocation, 12U> SameSignatureVirtualMethods{};
const auto *MPT = cast<MemberPointerType>(DRE->getType().getCanonicalType());
- const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+ const Type *T = MPT->getClass();
+ if (T == nullptr)
+ return;
+ const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
if (RD == nullptr)
return;
diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
index b66cc8512fad6..0fea7946a59f9 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -219,8 +219,8 @@ bool isQualificationConvertiblePointer(QualType From, QualType To,
if (P1->isMemberPointerType())
return P2->isMemberPointerType() &&
- P1->getAs<MemberPointerType>()->getMostRecentCXXRecordDecl() ==
- P2->getAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
+ P1->getAs<MemberPointerType>()->getClass() ==
+ P2->getAs<MemberPointerType>()->getClass();
if (P1->isConstantArrayType())
return P2->isConstantArrayType() &&
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h
index 50d1ba1b8f63f..6699284d215bd 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -454,8 +454,6 @@ struct CanProxyAdaptor<MemberPointerType>
: public CanProxyBase<MemberPointerType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const CXXRecordDecl *,
- getMostRecentCXXRecordDecl)
};
// CanProxyAdaptors for arrays are intentionally unimplemented because
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 9724f0def743a..0befe615c4ee1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5769,11 +5769,10 @@ class Sema final : public SemaBase {
/// Determine whether the type \p Derived is a C++ class that is
/// derived from the type \p Base.
- bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
- CXXRecordDecl *Base, CXXBasePaths &Paths);
- bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
- CXXRecordDecl *Base);
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base);
+
+ /// Determine whether the type \p Derived is a C++ class that is
+ /// derived from the type \p Base.
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base,
CXXBasePaths &Paths);
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 9dc02b25f8495..91640c4eb5cf9 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -238,9 +238,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>();
const auto *ToMP = CE->getType()->getAs<MemberPointerType>();
- unsigned DerivedOffset =
- Ctx.collectBaseOffset(ToMP->getMostRecentCXXRecordDecl(),
- FromMP->getMostRecentCXXRecordDecl());
+ unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0),
+ QualType(FromMP->getClass(), 0));
if (!this->delegate(SubExpr))
return false;
@@ -254,9 +253,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>();
const auto *ToMP = CE->getType()->getAs<MemberPointerType>();
- unsigned DerivedOffset =
- Ctx.collectBaseOffset(FromMP->getMostRecentCXXRecordDecl(),
- ToMP->getMostRecentCXXRecordDecl());
+ unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0),
+ QualType(ToMP->getClass(), 0));
if (!this->delegate(SubExpr))
return false;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 92a28897cf3ee..0165a0a3b0df3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10551,9 +10551,8 @@ bool MemberPointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
if (!Result.castToDerived(Derived))
return Error(E);
}
- if (!Result.castToDerived(E->getType()
- ->castAs<MemberPointerType>()
- ->getMostRecentCXXRecordDecl()))
+ const Type *FinalTy = E->getType()->castAs<MemberPointerType>()->getClass();
+ if (!Result.castToDerived(FinalTy->getAsCXXRecordDecl()))
return Error(E);
return true;
}
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 15de407e122d8..fe34251688a98 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -695,7 +695,7 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
mangleQualifiers(MPT->getPointeeType().getQualifiers(), true);
// Member pointers are suffixed with a back reference to the member
// pointer's class name.
- mangleName(MPT->getMostRecentCXXRecordDecl());
+ mangleName(MPT->getClass()->getAsCXXRecordDecl());
} else
mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
} else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
@@ -3331,11 +3331,11 @@ void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,
manglePointerExtQualifiers(Quals, PointeeType);
if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
Out << '8';
- mangleName(T->getMostRecentCXXRecordDecl());
+ mangleName(T->getClass()->castAs<RecordType>()->getDecl());
mangleFunctionType(FPT, nullptr, true);
} else {
mangleQualifiers(PointeeType.getQualifiers(), true);
- mangleName(T->getMostRecentCXXRecordDecl());
+ mangleName(T->getClass()->castAs<RecordType>()->getDecl());
mangleType(PointeeType, Range, QMM_Drop);
}
}
@@ -4309,11 +4309,11 @@ void MicrosoftCXXNameMangler::mangleAutoReturnType(const MemberPointerType *T,
manglePointerExtQualifiers(Quals, PointeeType);
if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
Out << '8';
- mangleName(T->getMostRecentCXXRecordDecl());
+ mangleName(T->getClass()->castAs<RecordType>()->getDecl());
mangleFunctionType(FPT, nullptr, true);
} else {
mangleQualifiers(PointeeType.getQualifiers(), true);
- mangleName(T->getMostRecentCXXRecordDecl());
+ mangleName(T->getClass()->castAs<RecordType>()->getDecl());
mangleAutoReturnType(PointeeType, QMM_Drop);
}
}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 33e7008cc4776..72161c06a88d4 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2446,17 +2446,19 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
// Member pointers in the MS ABI have special behavior in
// RequireCompleteType: they attach a MSInheritanceAttr to the CXXRecordDecl
// to indicate which inheritance model to use.
- // The inheritance attribute might only be present on the most recent
- // CXXRecordDecl.
- const CXXRecordDecl *RD =
- cast<MemberPointerType>(CanonicalType)->getMostRecentCXXRecordDecl();
+ auto *MPTy = cast<MemberPointerType>(CanonicalType);
+ const Type *ClassTy = MPTy->getClass();
// Member pointers with dependent class types don't get special treatment.
- if (!RD)
+ if (ClassTy->isDependentType())
return false;
+ const CXXRecordDecl *RD = ClassTy->getAsCXXRecordDecl();
ASTContext &Context = RD->getASTContext();
// Member pointers not in the MS ABI don't get special treatment.
if (!Context.getTargetInfo().getCXXABI().isMicrosoft())
return false;
+ // The inheritance attribute might only be present on the most recent
+ // CXXRecordDecl, use that one.
+ RD = RD->getMostRecentNonInjectedDecl();
// Nothing interesting to do if the inheritance attribute is already set.
if (RD->hasAttr<MSInheritanceAttr>())
return false;
@@ -4711,8 +4713,7 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
return computeTypeLinkageInfo(cast<ReferenceType>(T)->getPointeeType());
case Type::MemberPointer: {
const auto *MPT = cast<MemberPointerType>(T);
- LinkageInfo LV =
- getDeclLinkageAndVisibility(MPT->getMostRecentCXXRecordDecl());
+ LinkageInfo LV = computeTypeLinkageInfo(MPT->getClass());
LV.merge(computeTypeLinkageInfo(MPT->getPointeeType()));
return LV;
}
@@ -5178,10 +5179,7 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {
}
CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
- auto *RD = getClass()->getAsCXXRecordDecl();
- if (!RD)
- return nullptr;
- return RD->getMostRecentNonInjectedDecl();
+ return getClass()->getAsCXXRecordDecl()->getMostRecentNonInjectedDecl();
}
void clang::FixedPointValueToString(SmallVectorImpl<char> &Str,
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index 2777c78d6459d..7c6dfc3e59d8c 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -50,7 +50,8 @@ CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer(
llvm::Value *MemPtr, const MemberPointerType *MPT) {
ErrorUnsupportedABI(CGF, "calls through member pointers");
- const auto *RD = MPT->getMostRecentCXXRecordDecl();
+ const auto *RD =
+ cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
ThisPtrForCall =
CGF.getAsNaturalPointerTo(This, CGF.getContext().getRecordType(RD));
const FunctionProtoType *FPT =
@@ -293,7 +294,7 @@ llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
derivedType = E->getType();
const CXXRecordDecl *derivedClass =
- derivedType->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
+ derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
return CGM.GetNonVirtualBaseClassOffset(derivedClass,
E->path_begin(),
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 98c93b5bb4883..fa69caa41936c 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -161,9 +161,10 @@ CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base,
QualType memberType = memberPtrType->getPointeeType();
CharUnits memberAlign =
CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo);
- memberAlign = CGM.getDynamicOffsetAlignment(
- base.getAlignment(), memberPtrType->getMostRecentCXXRecordDecl(),
- memberAlign);
+ memberAlign =
+ CGM.getDynamicOffsetAlignment(base.getAlignment(),
+ memberPtrType->getClass()->getAsCXXRecordDecl(),
+ memberAlign);
return Address(ptr, ConvertTypeForMem(memberPtrType->getPointeeType()),
memberAlign);
}
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index dcccbc0835d95..c462b02676813 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3490,8 +3490,7 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty,
}
}
- llvm::DIType *ClassType = getOrCreateType(
- QualType(Ty->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0), U);
+ llvm::DIType *ClassType = getOrCreateType(QualType(Ty->getClass(), 0), U);
if (Ty->isMemberDataPointerType())
return DBuilder.createMemberPointerType(
getOrCreateType(Ty->getPointeeType(), U), ClassType, Size, /*Align=*/0,
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 5d96959065dd9..f71c18a8041b1 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -453,7 +453,8 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
const auto *MPT = MemFnExpr->getType()->castAs<MemberPointerType>();
const auto *FPT = MPT->getPointeeType()->castAs<FunctionProtoType>();
- const auto *RD = MPT->getMostRecentCXXRecordDecl();
+ const auto *RD =
+ cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
// Emit the 'this' pointer.
Address This = Address::invalid();
@@ -462,9 +463,8 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
else
This = EmitLValue(BaseExpr, KnownNonNull).getAddress();
- EmitTypeCheck(
- TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this),
- QualType(MPT->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0));
+ EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this),
+ QualType(MPT->getClass(), 0));
// Get the member function pointer.
llvm::Value *MemFnPtr = EmitScalarExpr(MemFnExpr);
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index 11cf5758b6d3a..dfbd444a850a5 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -728,7 +728,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
case Type::MemberPointer: {
auto *MPTy = cast<MemberPointerType>(Ty);
if (!getCXXABI().isMemberPointerConvertible(MPTy)) {
- auto *C = MPTy->getMostRecentCXXRecordDecl()->getTypeForDecl();
+ auto *C = MPTy->getClass();
auto Insertion = RecordsWithOpaqueMemberPointers.insert({C, nullptr});
if (Insertion.second)
Insertion.first->second = llvm::StructType::create(getLLVMContext());
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index a5633f6349ffa..7e26a0da3d7d2 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -628,7 +628,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
const FunctionProtoType *FPT =
MPT->getPointeeType()->castAs<FunctionProtoType>();
- auto *RD = MPT->getMostRecentCXXRecordDecl();
+ auto *RD =
+ cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
@@ -797,7 +798,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
// Check the function pointer if CFI on member function pointers is enabled.
if (ShouldEmitCFICheck) {
- CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+ CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
if (RD->hasDefinition()) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
@@ -3798,8 +3799,7 @@ static bool ContainsIncompleteClassType(QualType Ty) {
if (const MemberPointerType *MemberPointerTy =
dyn_cast<MemberPointerType>(Ty)) {
// Check if the class type is incomplete.
- const auto *ClassType = cast<RecordType>(
- MemberPointerTy->getMostRecentCXXRecordDecl()->getTypeForDecl());
+ const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
if (IsIncompleteClassType(ClassType))
return true;
@@ -4538,8 +4538,7 @@ ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
// attributes of the type pointed to.
unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy);
- const auto *ClassType =
- cast<RecordType>(Ty->getMostRecentCXXRecordDecl()->getTypeForDecl());
+ const RecordType *ClassType = cast<RecordType>(Ty->getClass());
if (IsIncompleteClassType(ClassType))
Flags |= PTI_ContainingClassIncomplete;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 7b2e0df8cb55d..a1551e8027cd3 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -3069,46 +3069,48 @@ void Sema::ActOnBaseSpecifiers(Decl *ClassDecl,
AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl), Bases);
}
-bool Sema::IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
- CXXRecordDecl *Base, CXXBasePaths &Paths) {
+bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base) {
if (!getLangOpts().CPlusPlus)
return false;
- if (!Base || !Derived)
+ CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl();
+ if (!DerivedRD)
+ return false;
+
+ CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl();
+ if (!BaseRD)
return false;
// If either the base or the derived type is invalid, don't try to
// check whether one is derived from the other.
- if (Base->isInvalidDecl() || Derived->isInvalidDecl())
+ if (BaseRD->isInvalidDecl() || DerivedRD->isInvalidDecl())
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 (!isCompleteType(Loc, Context.getTypeDeclType(Derived)) &&
- !Derived->isBeingDefined())
+ if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined())
return false;
- return Derived->isDerivedFrom(Base, Paths);
-}
-
-bool Sema::IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
- CXXRecordDecl *Base) {
- CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
- /*DetectVirtual=*/false);
- return IsDerivedFrom(Loc, Derived, Base, Paths);
-}
-
-bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base) {
- CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
- /*DetectVirtual=*/false);
- return IsDerivedFrom(Loc, Derived->getAsCXXRecordDecl(),
- Base->getAsCXXRecordDecl(), Paths);
+ return DerivedRD->isDerivedFrom(BaseRD);
}
bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base,
CXXBasePaths &Paths) {
- return IsDerivedFrom(Loc, Derived->getAsCXXRecordDecl(),
- Base->getAsCXXRecordDecl(), Paths);
+ if (!getLangOpts().CPlusPlus)
+ return false;
+
+ CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl();
+ if (!DerivedRD)
+ return false;
+
+ CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl();
+ if (!BaseRD)
+ return false;
+
+ if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined())
+ return false;
+
+ return DerivedRD->isDerivedFrom(BaseRD, Paths);
}
static void BuildBasePathArray(const CXXBasePath &Path,
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 8f204b949cb2c..cbea98b8884e9 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6529,7 +6529,7 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
return QualType();
}
- CXXRecordDecl *RHSClass = MemPtr->getMostRecentCXXRecordDecl();
+ QualType Class(MemPtr->getClass(), 0);
// Note: C++ [expr.mptr.oper]p2-3 says that the class type into which the
// member pointer points must be completely-defined. However, there is no
@@ -6552,16 +6552,15 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
return QualType();
}
}
- CXXRecordDecl *LHSClass = LHSType->getAsCXXRecordDecl();
- if (!declaresSameEntity(LHSClass, RHSClass)) {
+ if (!Context.hasSameUnqualifiedType(Class, LHSType)) {
// If we want to check the hierarchy, we need a complete type.
if (RequireCompleteType(Loc, LHSType, diag::err_bad_memptr_lhs,
OpSpelling, (int)isIndirect)) {
return QualType();
}
- if (!IsDerivedF...
[truncated]
|
Reverts #131965
Reverted due to issue reported here: #131965 (comment)