Skip to content
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

[Sema]Use tag name lookup for class names #112166

Merged
merged 1 commit into from
Oct 15, 2024

Conversation

spaits
Copy link
Contributor

@spaits spaits commented Oct 14, 2024

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."

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Oct 14, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 14, 2024

@llvm/pr-subscribers-clang

Author: Gábor Spaits (spaits)

Changes

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."

Full diff: https://github.com/llvm/llvm-project/pull/112166.diff

2 Files Affected:

  • (modified) clang/lib/Sema/SemaDecl.cpp (+5-3)
  • (modified) clang/test/CXX/class.derived/p2.cpp (+12)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 118873bc93ad4b..5cce92ef118951 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -357,9 +357,10 @@ 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 :
+  // In case 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.
+  LookupNameKind Kind = isClassName ? LookupTagName :
                                       LookupOrdinaryName;
   LookupResult Result(*this, &II, NameLoc, Kind);
   if (LookupCtx) {
@@ -547,6 +548,7 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
   if (T.isNull()) {
     // If it's not plausibly a type, suppress diagnostics.
     Result.suppressDiagnostics();
+    llvm::errs() << "Not a type\n";
     return nullptr;
   }
 
diff --git a/clang/test/CXX/class.derived/p2.cpp b/clang/test/CXX/class.derived/p2.cpp
index 87e0f748615456..588436c3a8d211 100644
--- a/clang/test/CXX/class.derived/p2.cpp
+++ b/clang/test/CXX/class.derived/p2.cpp
@@ -7,3 +7,15 @@ namespace PR5840 {
   int Base = 10;
   struct Derived : Base {};
 }
+
+namespace issue_number {
+  struct x {};
+  namespace
+  {
+      namespace x
+      {
+          struct y : x
+          {};
+      }
+  }
+}
\ No newline at end of file

Copy link

github-actions bot commented Oct 14, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@spaits spaits requested a review from hokein October 14, 2024 08:23
@spaits spaits changed the title Use tag name lookup for class names [Sema]Use tag name lookup for class names Oct 14, 2024
Copy link
Member

@Sirraide Sirraide left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the implementation is fine. This still needs a release note, though.

clang/lib/Sema/SemaDecl.cpp Outdated Show resolved Hide resolved
clang/test/CXX/class.derived/p2.cpp Outdated Show resolved Hide resolved
@spaits
Copy link
Contributor Author

spaits commented Oct 14, 2024

Thank you @Sirraide for reviewing my PR. I have added this change to the release notes and addressed the other comments.

clang/docs/ReleaseNotes.rst Outdated Show resolved Hide resolved
clang/lib/Sema/SemaDecl.cpp Outdated Show resolved Hide resolved
Copy link
Member

@Sirraide Sirraide left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

clang/docs/ReleaseNotes.rst Outdated Show resolved Hide resolved
@spaits
Copy link
Contributor Author

spaits commented Oct 14, 2024

Thank you @Sirraide for reviewing. I will wait a few hours if other also want to take a look at this, then I will squash the commits and merge the changes.

Copy link
Collaborator

@erichkeane erichkeane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 nit, else LGTM.

clang/lib/Sema/SemaDecl.cpp Outdated Show resolved Hide resolved
@spaits spaits force-pushed the ignore-non-type-names branch 2 times, most recently from 64aa2ad to 6935e90 Compare October 14, 2024 18:23
This PR would fix llvm#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."
```
@spaits spaits force-pushed the ignore-non-type-names branch from 6935e90 to 4afa9c5 Compare October 15, 2024 08:00
@spaits
Copy link
Contributor Author

spaits commented Oct 15, 2024

The windows CI passes. The linux CI fails, but it also fails on other clang fronted PRs (see #112289 for example). I think this failure is unrelated to this PR. I will merge this.

@spaits spaits merged commit 4852120 into llvm:main Oct 15, 2024
6 of 8 checks passed
DanielCChen pushed a commit to DanielCChen/llvm-project that referenced this pull request Oct 16, 2024
This PR would fix llvm#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.
```
bricknerb pushed a commit to bricknerb/llvm-project that referenced this pull request Oct 17, 2024
This PR would fix llvm#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.
```
EricWF pushed a commit to efcs/llvm-project that referenced this pull request Oct 22, 2024
This PR would fix llvm#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.
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

during the lookup for a base class name, non-type names should be ignored
4 participants