-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Conversation
@llvm/pr-subscribers-clang Author: Gábor Spaits (spaits) ChangesThis 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:
Full diff: https://github.com/llvm/llvm-project/pull/112166.diff 2 Files Affected:
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
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this 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.
Thank you @Sirraide for reviewing my PR. I have added this change to the release notes and addressed the other comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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. |
There was a problem hiding this 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.
64aa2ad
to
6935e90
Compare
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." ```
6935e90
to
4afa9c5
Compare
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. |
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. ```
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. ```
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. ```
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: