[clang] [Sema]Use tag name lookup for class names (PR #112166)

Gábor Spaits via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 14 11:20:00 PDT 2024


https://github.com/spaits updated https://github.com/llvm/llvm-project/pull/112166

>From 64aa2ad0fa41ac93db311c70d4113886fd4d6ffd Mon Sep 17 00:00:00 2001
From: Gabor Spaits <gaborspaits1 at gmail.com>
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 e48835d4738007..8d3fbcf14c6a52 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -494,6 +494,7 @@ Bug Fixes to C++ Support
 - Fix a crash when parsing a pseudo destructor involving an invalid type. (#GH111460)
 - Fixed an assertion failure when invoking recovery call expressions with explicit attributes
   and undeclared templates. (#GH107047, #GH49093)
+- 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 118873bc93ad4b..d54a763ddbb180 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 87e0f748615456..401ee37ad6b64c 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



More information about the cfe-commits mailing list