[clang] 90010c2 - Don't consider 'LinkageSpec' when calculating DeclContext 'Encloses'

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 29 06:24:48 PST 2021


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
+}
+}


        


More information about the cfe-commits mailing list