ChuanqiXu created this revision.
ChuanqiXu added reviewers: rsmith, aaron.ballman.
ChuanqiXu added a project: clang.
ChuanqiXu requested review of this revision.
Herald added a subscriber: cfe-commits.

This fixes https://bugs.llvm.org/show_bug.cgi?id=47116.

According to https://eel.is/c++draft/module.interface#6, it is meaningless to 
export an entity which is not in namespace scope.

And the reason why the compiler crashes is that the compiler missed 
`ExportDecl` when the compiler traverse the subclass of `DeclContext`. So here 
is the crash.

Test Plan: check-all


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D112903

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/module/module.interface/p6.cpp


Index: clang/test/CXX/module/module.interface/p6.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/module/module.interface/p6.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify
+
+export module X;
+
+export template <typename T>
+struct btree_set {
+  struct iterator {
+    T node;
+  };
+};
+
+export template <typename T> btree_set<T>::iterator; // expected-error 
{{cannot export 'iterator' here because it had be declared in 'btree_set'}}
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -5745,6 +5745,9 @@
     else if (isa<BlockDecl>(Cur))
       Diag(Loc, diag::err_invalid_declarator_in_block)
         << Name << SS.getRange();
+    else if (isa<ExportDecl>(Cur))
+      Diag(Loc, diag::err_invalid_declarator_in_export)
+          << Name << cast<NamedDecl>(DC) << SS.getRange();
     else
       Diag(Loc, diag::err_invalid_declarator_scope)
       << Name << cast<NamedDecl>(Cur) << cast<NamedDecl>(DC) << SS.getRange();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7781,6 +7781,8 @@
   "%select{ or namespace|, namespace, or enumeration}1">;
 def err_invalid_declarator_scope : Error<"cannot define or redeclare %0 here "
   "because namespace %1 does not enclose namespace %2">;
+def err_invalid_declarator_in_export : Error<"cannot export %0 here "
+  "because it had be declared in %1.">;
 def err_invalid_declarator_global_scope : Error<
   "definition or redeclaration of %0 cannot name the global scope">;
 def err_invalid_declarator_in_function : Error<


Index: clang/test/CXX/module/module.interface/p6.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/module/module.interface/p6.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify
+
+export module X;
+
+export template <typename T>
+struct btree_set {
+  struct iterator {
+    T node;
+  };
+};
+
+export template <typename T> btree_set<T>::iterator; // expected-error {{cannot export 'iterator' here because it had be declared in 'btree_set'}}
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -5745,6 +5745,9 @@
     else if (isa<BlockDecl>(Cur))
       Diag(Loc, diag::err_invalid_declarator_in_block)
         << Name << SS.getRange();
+    else if (isa<ExportDecl>(Cur))
+      Diag(Loc, diag::err_invalid_declarator_in_export)
+          << Name << cast<NamedDecl>(DC) << SS.getRange();
     else
       Diag(Loc, diag::err_invalid_declarator_scope)
       << Name << cast<NamedDecl>(Cur) << cast<NamedDecl>(DC) << SS.getRange();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7781,6 +7781,8 @@
   "%select{ or namespace|, namespace, or enumeration}1">;
 def err_invalid_declarator_scope : Error<"cannot define or redeclare %0 here "
   "because namespace %1 does not enclose namespace %2">;
+def err_invalid_declarator_in_export : Error<"cannot export %0 here "
+  "because it had be declared in %1.">;
 def err_invalid_declarator_global_scope : Error<
   "definition or redeclaration of %0 cannot name the global scope">;
 def err_invalid_declarator_in_function : Error<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to