aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/CXXInheritance.cpp
diff options
context:
space:
mode:
authorVladislav Belov <vladislav.belov@syntacore.com>2024-12-03 16:46:01 +0300
committerGitHub <noreply@github.com>2024-12-03 16:46:01 +0300
commite1cb316cfd99208363b5eb9bf96430ca28020be0 (patch)
tree8e381a134b5c5c1357d98401b49f991d23cc6152 /clang/lib/AST/CXXInheritance.cpp
parent2a0ee090dbb9af80222bc796ac34fd4b7cba421b (diff)
downloadllvm-e1cb316cfd99208363b5eb9bf96430ca28020be0.zip
llvm-e1cb316cfd99208363b5eb9bf96430ca28020be0.tar.gz
llvm-e1cb316cfd99208363b5eb9bf96430ca28020be0.tar.bz2
Reapply "[clang] Fix name lookup for dependent bases" (#118003)
Unlike the previous version (https://github.com/llvm/llvm-project/pull/114978), this patch also removes an unnecessary assert that causes Clang to crash when compiling such tests. (clang/lib/AST/DeclCXX.cpp) https://lab.llvm.org/buildbot/#/builders/52/builds/4021 ```c++ template <class T> class X { public: X() = default; virtual ~X() = default; virtual int foo(int x, int y, T &entry) = 0; void bar() { struct Y : public X<T> { Y() : X() {} int foo(int, int, T &) override { return 42; } }; } }; ``` the assertions: ```c++ llvm-project/clang/lib/AST/DeclCXX.cpp:2508: void clang::CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *): Assertion `!MD->getParent()->isDependentContext() && "Can't add an overridden method to a class template!"' failed. ``` I believe that this assert is unnecessary and contradicts the logic of this patch. After its removal, Clang was successfully built using itself, and all tests passed.
Diffstat (limited to 'clang/lib/AST/CXXInheritance.cpp')
-rw-r--r--clang/lib/AST/CXXInheritance.cpp18
1 files changed, 12 insertions, 6 deletions
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp
index aefc06e..10b8d52 100644
--- a/clang/lib/AST/CXXInheritance.cpp
+++ b/clang/lib/AST/CXXInheritance.cpp
@@ -134,7 +134,7 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches) const {
return false;
CXXRecordDecl *Base =
- cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition());
+ cast_if_present<CXXRecordDecl>(Ty->getDecl()->getDefinition());
if (!Base ||
(Base->isDependentContext() &&
!Base->isCurrentInstantiation(Record))) {
@@ -169,13 +169,21 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
QualType BaseType =
Context.getCanonicalType(BaseSpec.getType()).getUnqualifiedType();
+ bool isCurrentInstantiation = isa<InjectedClassNameType>(BaseType);
+ if (!isCurrentInstantiation) {
+ if (auto *BaseRecord = cast_if_present<CXXRecordDecl>(
+ BaseSpec.getType()->getAsRecordDecl()))
+ isCurrentInstantiation = BaseRecord->isDependentContext() &&
+ BaseRecord->isCurrentInstantiation(Record);
+ }
// C++ [temp.dep]p3:
// In the definition of a class template or a member of a class template,
// if a base class of the class template depends on a template-parameter,
// the base class scope is not examined during unqualified name lookup
// either at the point of definition of the class template or member or
// during an instantiation of the class tem- plate or member.
- if (!LookupInDependent && BaseType->isDependentType())
+ if (!LookupInDependent &&
+ (BaseType->isDependentType() && !isCurrentInstantiation))
continue;
// Determine whether we need to visit this base class at all,
@@ -243,9 +251,8 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
return FoundPath;
}
} else if (VisitBase) {
- CXXRecordDecl *BaseRecord;
+ CXXRecordDecl *BaseRecord = nullptr;
if (LookupInDependent) {
- BaseRecord = nullptr;
const TemplateSpecializationType *TST =
BaseSpec.getType()->getAs<TemplateSpecializationType>();
if (!TST) {
@@ -264,8 +271,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
BaseRecord = nullptr;
}
} else {
- BaseRecord = cast<CXXRecordDecl>(
- BaseSpec.getType()->castAs<RecordType>()->getDecl());
+ BaseRecord = cast<CXXRecordDecl>(BaseSpec.getType()->getAsRecordDecl());
}
if (BaseRecord &&
lookupInBases(Context, BaseRecord, BaseMatches, LookupInDependent)) {