Skip to content

Revert "[Clang] Fix name lookup for dependent bases (#114978)" #117727

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

Merged
merged 1 commit into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,6 @@ Resolutions to C++ Defect Reports
by default.
(`CWG2521: User-defined literals and reserved identifiers <https://cplusplus.github.io/CWG/issues/2521.html>`_).

- Fix name lookup for a dependent base class that is the current instantiation.
(`CWG591: When a dependent base class is the current instantiation <https://cplusplus.github.io/CWG/issues/591.html>`_).

C Language Changes
------------------

Expand Down
18 changes: 6 additions & 12 deletions clang/lib/AST/CXXInheritance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches) const {
return false;

CXXRecordDecl *Base =
cast_if_present<CXXRecordDecl>(Ty->getDecl()->getDefinition());
cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition());
if (!Base ||
(Base->isDependentContext() &&
!Base->isCurrentInstantiation(Record))) {
Expand Down Expand Up @@ -169,21 +169,13 @@ 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() && !isCurrentInstantiation))
if (!LookupInDependent && BaseType->isDependentType())
continue;

// Determine whether we need to visit this base class at all,
Expand Down Expand Up @@ -251,8 +243,9 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
return FoundPath;
}
} else if (VisitBase) {
CXXRecordDecl *BaseRecord = nullptr;
CXXRecordDecl *BaseRecord;
if (LookupInDependent) {
BaseRecord = nullptr;
const TemplateSpecializationType *TST =
BaseSpec.getType()->getAs<TemplateSpecializationType>();
if (!TST) {
Expand All @@ -271,7 +264,8 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
BaseRecord = nullptr;
}
} else {
BaseRecord = cast<CXXRecordDecl>(BaseSpec.getType()->getAsRecordDecl());
BaseRecord = cast<CXXRecordDecl>(
BaseSpec.getType()->castAs<RecordType>()->getDecl());
}
if (BaseRecord &&
lookupInBases(Context, BaseRecord, BaseMatches, LookupInDependent)) {
Expand Down
48 changes: 2 additions & 46 deletions clang/test/CXX/drs/cwg5xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1178,61 +1178,17 @@ namespace cwg590 { // cwg590: yes
template<typename T> typename A<T>::B::C A<T>::B::C::f(A<T>::B::C) {}
}

namespace cwg591 { // cwg591: yes
namespace cwg591 { // cwg591: no
template<typename T> struct A {
typedef int M;
struct B {
typedef void M;
struct C;
struct D;
};
};

template<typename T> struct G {
struct B {
typedef int M;
struct C {
typedef void M;
struct D;
};
};
};

template<typename T> struct H {
template<typename U> struct B {
typedef int M;
template<typename F> struct C {
typedef void M;
struct D;
struct P;
};
};
};

template<typename T> struct A<T>::B::C : A<T> {
M m;
};

template<typename T> struct G<T>::B::C::D : B {
M m;
};

template<typename T>
template<typename U>
template<typename F>
struct H<T>::B<U>::C<F>::D : B<U> {
M m;
};

template<typename T> struct A<T>::B::D : A<T*> {
M m;
// expected-error@-1 {{field has incomplete type 'M' (aka 'void'}}
};

template<typename T>
template<typename U>
template<typename F>
struct H<T>::B<U>::C<F>::P : B<F> {
// FIXME: Should find member of non-dependent base class A<T>.
M m;
// expected-error@-1 {{field has incomplete type 'M' (aka 'void'}}
};
Expand Down
2 changes: 1 addition & 1 deletion clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -3599,7 +3599,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/591.html">591</a></td>
<td>CD4</td>
<td>When a dependent base class is the current instantiation</td>
<td class="none" align="center">Yes</td>
<td class="none" align="center">No</td>
</tr>
<tr id="592">
<td><a href="https://cplusplus.github.io/CWG/issues/592.html">592</a></td>
Expand Down
Loading