Author: Erich Keane Date: 2021-11-29T06:08:16-08:00 New Revision: 90010c2e1d60c6a9a4a0b30a113d4dae2b7214eb
URL: https://github.com/llvm/llvm-project/commit/90010c2e1d60c6a9a4a0b30a113d4dae2b7214eb DIFF: https://github.com/llvm/llvm-project/commit/90010c2e1d60c6a9a4a0b30a113d4dae2b7214eb.diff LOG: Don't consider 'LinkageSpec' when calculating DeclContext 'Encloses' We don't properly handle lookup through using directives when there is a linkage spec in the common chain. This is because `CppLookupName` and `CppNamespaceLookup` end up skipping `LinkageSpec`'s (correctly, as they are not lookup scopes), but the `UnqualUsingDirectiveSet` does not. I discovered that when we are calculating the `CommonAncestor` for a using-directive, we were coming up with the `LinkageSpec`, instead of the `LinkageSpec`'s parent. Then, when we use `UnqualUsingDirectiveSet::getNamespacesFor` a scope, we don't end up finding any that were in the `LinkageSpec` (again, since `CppLookupName` skips linkage specs), so those don't end up participating in the lookup. The function `UnqualUsingDirectiveSet::addUsingDirective` calculates this common ancestor via a loop through the the `DeclSpec::Encloses` function. Changing this Encloses function to believe that a `LinkageSpec` `Encloses` nothing ends up fixing the problem without breaking any other tests, so I opted to do that. A less aggressive patch could perhaps change only the `addUsingDirective`, but my examination of all uses of `Encloses` showed that it seems to be used exclusively in lookup, which makes me think this is correct everywhere. Differential Revision: https://reviews.llvm.org/D113709 Added: clang/test/SemaCXX/lookup-through-linkage.cpp Modified: clang/lib/AST/DeclBase.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index d8eaf706384f5..064012ba865c8 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -1212,7 +1212,7 @@ bool DeclContext::Encloses(const DeclContext *DC) const { return getPrimaryContext()->Encloses(DC); for (; DC; DC = DC->getParent()) - if (DC->getPrimaryContext() == this) + if (!isa<LinkageSpecDecl>(DC) && DC->getPrimaryContext() == this) return true; return false; } diff --git a/clang/test/SemaCXX/lookup-through-linkage.cpp b/clang/test/SemaCXX/lookup-through-linkage.cpp new file mode 100644 index 0000000000000..0a2d609e9dbd9 --- /dev/null +++ b/clang/test/SemaCXX/lookup-through-linkage.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 %s -verify + +// expected-no-diagnostics + +extern "C++" { +namespace A { +namespace B { +int bar; +} +} // namespace A +namespace C { +void foo() { + using namespace A; + (void)B::bar; +} +} // namespace C +} + +extern "C" { +extern "C++" { +namespace D { +namespace E { +int bar; +} +} // namespace A +namespace F { +void foo() { + using namespace D; + (void)E::bar; +} +} // namespace C +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits