-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[clang] Fix a bug with qualified name lookup into current instantiation #73018
Conversation
Due to d0d2ee0 clang doesn't perform qualified name lookup into the current instantiation when it has dependent bases, because of that `getTypeName` call always returns null for unknown specialization case. When there is a `typename` keyword, `DependentNameType` is constructed instead of simply returning null. This change attempts to do the same in case of `typename` absence. Fixes llvm#13826
@llvm/pr-subscribers-clang Author: Mariya Podchishchaeva (Fznamznon) ChangesDue to d0d2ee0 clang doesn't perform qualified name lookup into the current instantiation when it has dependent bases, because of that Fixes #13826 Full diff: https://github.com/llvm/llvm-project/pull/73018.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 157afd9e8629152..09ceb591d06eab5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -610,6 +610,9 @@ Bug Fixes in This Version
inside a lambda. (`#61460 <https://github.com/llvm/llvm-project/issues/61460>`_)
- Fix crash during instantiation of some class template specializations within class
templates. Fixes (`#70375 <https://github.com/llvm/llvm-project/issues/70375>`_)
+- Fixed false positive error emitted by clang when performing qualified name
+ lookup and the current class instantiation has dependent bases.
+ Fixes (`#13826 <https://github.com/llvm/llvm-project/issues/13826>`_)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4e1857b931cc868..71003c1815c90e4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -442,7 +442,6 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
UsingShadowDecl *FoundUsingShadow = nullptr;
switch (Result.getResultKind()) {
case LookupResult::NotFound:
- case LookupResult::NotFoundInCurrentInstantiation:
if (CorrectedII) {
TypeNameValidatorCCC CCC(/*AllowInvalid=*/true, isClassName,
AllowDeducedTemplate);
@@ -482,8 +481,23 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
}
}
}
- // If typo correction failed or was not performed, fall through
- [[fallthrough]];
+ Result.suppressDiagnostics();
+ return nullptr;
+ case LookupResult::NotFoundInCurrentInstantiation: {
+ if (AllowImplicitTypename == ImplicitTypenameContext::Yes) {
+ QualType T;
+ T = Context.getDependentNameType(ElaboratedTypeKeyword::None,
+ SS->getScopeRep(), &II);
+ TypeLocBuilder TLB;
+ DependentNameTypeLoc TL = TLB.push<DependentNameTypeLoc>(T);
+ TL.setElaboratedKeywordLoc(SourceLocation());
+ TL.setQualifierLoc(SS->getWithLocInContext(Context));
+ TL.setNameLoc(NameLoc);
+ return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
+ }
+ Result.suppressDiagnostics();
+ return nullptr;
+ }
case LookupResult::FoundOverloaded:
case LookupResult::FoundUnresolvedValue:
Result.suppressDiagnostics();
diff --git a/clang/test/SemaTemplate/dependent-base-classes.cpp b/clang/test/SemaTemplate/dependent-base-classes.cpp
index 09f475f8bde9183..92a37efaa7e73f6 100644
--- a/clang/test/SemaTemplate/dependent-base-classes.cpp
+++ b/clang/test/SemaTemplate/dependent-base-classes.cpp
@@ -130,3 +130,17 @@ namespace PR5812 {
Derived<int> di;
}
+
+namespace GH13826 {
+template <typename T> struct A {
+ typedef int type;
+ struct B;
+};
+
+template <typename T> struct A<T>::B : A<T> {
+ B::type t;
+};
+
+A<int> a;
+A<int>::B b;
+}
|
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.
The patch makes sense to me, though my knowledge of this function is limited. Please give @cor3ntin a chance to look at it too in case he sees something I don't.
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.
That looks reasonable to me modulo nit and @shafik comments.
Thanks for fixing this!
clang/lib/Sema/SemaDecl.cpp
Outdated
SS->getScopeRep(), &II); | ||
TypeLocBuilder TLB; | ||
DependentNameTypeLoc TL = TLB.push<DependentNameTypeLoc>(T); | ||
TL.setElaboratedKeywordLoc(SourceLocation()); |
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 don't think that's actually needed even if we do it in a bunch of places.
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.
Oh, we probably need this. Sanitizer build failed due to elaborated keyword loc not initialized https://lab.llvm.org/buildbot/#/builders/5/builds/38796/steps/2/logs/stdio .
Fix for buildbot #73928 |
As a result of this commit clang no longer gives an error for
where gcc (though not msvc) gives an error: https://godbolt.org/z/qGfnzhfsK |
I'm not completely sure if we should be giving an error for the example I gave above. Looking through the C++20 standard I see temp.res paragraph 2:
The error that gcc is giving is
so I'm guessing that gcc thinks that the name lookup for
Maybe the rule in temp.res doesn't apply because this is a member of the template and not the template itself? |
I'm not sure I understand why gcc is giving an error in https://godbolt.org/z/qGfnzhfsK. It doesn't give an error with |
Was this PR meant to change the behaviour for c++11/14? |
This looks like a GCC bug to me. I think the presence or absence of |
Due to d0d2ee0 clang doesn't perform qualified name lookup into the current instantiation when it has dependent bases, because of that
getTypeName
call always returns null for unknown specialization case. When there is atypename
keyword,DependentNameType
is constructed instead of simply returning null.This change attempts to do the same in case of
typename
absence.Fixes #13826