[PATCH] D108403: Fix assertion when generating diagnostic for inline namespaces

Aaron Ballman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 20 05:22:51 PDT 2021


aaron.ballman updated this revision to Diff 367765.
aaron.ballman added a comment.

Updating based on review comments.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D108403/new/

https://reviews.llvm.org/D108403

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/DeclBase.h
  clang/lib/AST/DeclBase.cpp
  clang/test/Misc/diag-inline-namespace.cpp


Index: clang/test/Misc/diag-inline-namespace.cpp
===================================================================
--- clang/test/Misc/diag-inline-namespace.cpp
+++ clang/test/Misc/diag-inline-namespace.cpp
@@ -48,3 +48,14 @@
   T<struct A::B::C::i> t4; // expected-error {{implicit instantiation of undefined template 'N::T<N::A::i>'}}
   T<struct A::B::C::j> t5; // expected-error {{implicit instantiation of undefined template 'N::T<N::B::C::j>'}}
 }
+
+namespace dont_crash {
+// A malformed lookup involving inline namespaces in a linkage specification
+// would previous cause an assertion due to the way diagnostics are emitted.
+extern "C++" inline namespace {
+namespace a {
+  a : b // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}} \
+        // expected-error {{no type named 'b' in namespace 'dont_crash::a'}}
+} // expected-error {{expected unqualified-id}}
+} // inline namespace
+} // dont_crash
Index: clang/lib/AST/DeclBase.cpp
===================================================================
--- clang/lib/AST/DeclBase.cpp
+++ clang/lib/AST/DeclBase.cpp
@@ -1217,6 +1217,13 @@
   return false;
 }
 
+DeclContext *DeclContext::getNonTransparentContext() {
+  DeclContext *DC = this;
+  while (DC && DC->isTransparentContext())
+    DC = DC->getParent();
+  return DC;
+}
+
 DeclContext *DeclContext::getPrimaryContext() {
   switch (getDeclKind()) {
   case Decl::ExternCContext:
Index: clang/include/clang/AST/DeclBase.h
===================================================================
--- clang/include/clang/AST/DeclBase.h
+++ clang/include/clang/AST/DeclBase.h
@@ -1997,6 +1997,12 @@
     return const_cast<DeclContext*>(this)->getNonClosureAncestor();
   }
 
+  // Retrieve the nearest context that is not a transparent context.
+  DeclContext *getNonTransparentContext();
+  const DeclContext* getNonTransparentContext() const {
+    return const_cast<DeclContext *>(this)->getNonTransparentContext();
+  }
+
   /// getPrimaryContext - There may be many different
   /// declarations of the same entity (including forward declarations
   /// of classes, multiple definitions of namespaces, etc.), each with
Index: clang/include/clang/AST/Decl.h
===================================================================
--- clang/include/clang/AST/Decl.h
+++ clang/include/clang/AST/Decl.h
@@ -614,7 +614,9 @@
     if (!isInline())
       return false;
     auto X = lookup(Name);
-    auto Y = getParent()->lookup(Name);
+    // We should not perform a lookup within a transparent context, so find a
+    // non-transparent parent context.
+    auto Y = getParent()->getNonTransparentContext()->lookup(Name);
     return std::distance(X.begin(), X.end()) ==
       std::distance(Y.begin(), Y.end());
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D108403.367765.patch
Type: text/x-patch
Size: 2763 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210820/b31d9345/attachment.bin>


More information about the cfe-commits mailing list