From 4afa9c58b3e662b8acab65f8afed820c3cbf54b5 Mon Sep 17 00:00:00 2001 From: Gabor Spaits Date: Mon, 14 Oct 2024 10:12:42 +0200 Subject: [PATCH] Use tag name lookup for class names This PR would fix #16855 . I think the correct lookup to use for class names is Tag name lookup, because it does not take namespaces into account. The current lookup does and because of this some valid programs are not accepted. If you think that Tag name lookup is not correct for all cases when we are looking up types based on class names then we can only do tag name lookup when looking up class names for inheritance. In case of inheritance: ``` [class.derived]p2 says: "During the lookup for a base class name, non-type names are ignored." ``` --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaDecl.cpp | 11 +++++++---- clang/test/CXX/class.derived/p2.cpp | 14 +++++++++++++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7ec13aa7af1ab..817e3abef8d56 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -516,6 +516,7 @@ Bug Fixes to C++ Support - Fixed a bug in lambda captures where ``constexpr`` class-type objects were not properly considered ODR-used in certain situations. (#GH47400), (#GH90896) - Fix erroneous templated array size calculation leading to crashes in generated code. (#GH41441) +- During the lookup for a base class name, non-type names are ignored. (#GH16855) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 40456bbf5d44b..fece22c663d00 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -357,10 +357,13 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, return nullptr; } - // FIXME: LookupNestedNameSpecifierName isn't the right kind of - // lookup for class-names. - LookupNameKind Kind = isClassName ? LookupNestedNameSpecifierName : - LookupOrdinaryName; + // In the case where we know that the identifier is a class name, we know that + // it is a type declaration (struct, class, union or enum) so we can use tag + // name lookup. + // + // 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. + LookupNameKind Kind = isClassName ? LookupTagName : LookupOrdinaryName; LookupResult Result(*this, &II, NameLoc, Kind); if (LookupCtx) { // Perform "qualified" name lookup into the declaration context we diff --git a/clang/test/CXX/class.derived/p2.cpp b/clang/test/CXX/class.derived/p2.cpp index 87e0f74861545..401ee37ad6b64 100644 --- a/clang/test/CXX/class.derived/p2.cpp +++ b/clang/test/CXX/class.derived/p2.cpp @@ -6,4 +6,16 @@ namespace PR5840 { struct Base {}; int Base = 10; struct Derived : Base {}; -} +} // namespace PR5840 + +namespace issue_16855 { + struct x {}; + namespace + { + namespace x + { + struct y : x + {}; + } // namespace x + } +} // namespace issue_16855