Skip to content

Commit 4852120

Browse files
authored
[Sema]Use tag name lookup for class names (#112166)
This PR would fix #16855 . The correct lookup to use for class names is Tag name lookup, because it does not take namespaces into account. The lookup before does and because of this some valid programs are not accepted. An example scenario of a valid program being declined is when you have a struct (let's call it `y`) inheriting from another struct with a name `x` but the struct `y` is in a namespace that is also called `x`: ``` struct x {}; namespace { namespace x { struct y : x {}; } } ``` This shall be accepted because: ``` C++ [class.derived]p2 (wrt lookup in a base-specifier): The lookup for // the component name of the type-name or simple-template-id is type-only. ```
1 parent 11903e8 commit 4852120

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ Bug Fixes to C++ Support
516516
- Fixed a bug in lambda captures where ``constexpr`` class-type objects were not properly considered ODR-used in
517517
certain situations. (#GH47400), (#GH90896)
518518
- Fix erroneous templated array size calculation leading to crashes in generated code. (#GH41441)
519+
- During the lookup for a base class name, non-type names are ignored. (#GH16855)
519520

520521
Bug Fixes to AST Handling
521522
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaDecl.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -357,10 +357,13 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
357357
return nullptr;
358358
}
359359

360-
// FIXME: LookupNestedNameSpecifierName isn't the right kind of
361-
// lookup for class-names.
362-
LookupNameKind Kind = isClassName ? LookupNestedNameSpecifierName :
363-
LookupOrdinaryName;
360+
// In the case where we know that the identifier is a class name, we know that
361+
// it is a type declaration (struct, class, union or enum) so we can use tag
362+
// name lookup.
363+
//
364+
// C++ [class.derived]p2 (wrt lookup in a base-specifier): The lookup for
365+
// the component name of the type-name or simple-template-id is type-only.
366+
LookupNameKind Kind = isClassName ? LookupTagName : LookupOrdinaryName;
364367
LookupResult Result(*this, &II, NameLoc, Kind);
365368
if (LookupCtx) {
366369
// Perform "qualified" name lookup into the declaration context we

clang/test/CXX/class.derived/p2.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,16 @@ namespace PR5840 {
66
struct Base {};
77
int Base = 10;
88
struct Derived : Base {};
9-
}
9+
} // namespace PR5840
10+
11+
namespace issue_16855 {
12+
struct x {};
13+
namespace
14+
{
15+
namespace x
16+
{
17+
struct y : x
18+
{};
19+
} // namespace x
20+
}
21+
} // namespace issue_16855

0 commit comments

Comments
 (0)