[PATCH] D112903: [C++20] [Module] Fix front end crashes when trying to export a qualified entity which is already declared
Chuanqi Xu via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 3 20:13:32 PDT 2021
ChuanqiXu updated this revision to Diff 384645.
ChuanqiXu retitled this revision from "[C++20] [Module] Fix front end crashes when trying to export a type out of a module " to "[C++20] [Module] Fix front end crashes when trying to export a qualified entity which is already declared".
ChuanqiXu added a comment.
Add more tests.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D112903/new/
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,52 @@
+// RUN: %clang_cc1 -std=c++20 %s -verify
+
+export module X;
+
+export template <typename T>
+struct X {
+ struct iterator {
+ T node;
+ };
+ void foo() {}
+ template <typename U>
+ U bar();
+};
+
+export template <typename T> X<T>::iterator; // expected-error {{cannot export 'iterator' here because it had be declared in 'X'}}
+export template <typename T> void X<T>::foo(); // expected-error {{cannot export 'foo' here because it had be declared in 'X'}}
+export template <typename T> template <typename U> U X<T>::bar(); // expected-error {{cannot export 'bar' here because it had be declared in 'X'}}
+
+export struct Y {
+ struct iterator {
+ int node;
+ };
+ void foo() {}
+ template <typename U>
+ U bar();
+};
+
+export struct Y::iterator; // expected-error {{cannot export 'iterator' here because it had be declared in 'Y'}}
+export void Y::foo(); // expected-error {{cannot export 'foo' here because it had be declared in 'Y'}}
+export template <typename U> U Y::bar(); // expected-error {{cannot export 'bar' here because it had be declared in 'Y'}}
+
+export {
+ template <typename T> X<T>::iterator; // expected-error {{cannot export 'iterator' here because it had be declared in 'X'}}
+ struct Y::iterator; // expected-error {{cannot export 'iterator' here because it had be declared in 'Y'}}
+}
+
+namespace A{
+ export struct X;
+ struct Y;
+ export void foo();
+ void bar();
+}
+
+// [module.interface]/p6
+// A redeclaration of an entity X is implicitly exported if X was introduced by an exported declaration
+void A::foo();
+export struct A::X; // expected-error {{cannot export 'X' here because it had be declared in 'A'}}
+export struct A::Y; // expected-error {{cannot export 'Y' here because it had be declared in 'A'.}}
+export void A::foo(); // expected-error {{cannot export 'foo' here because it had be declared in 'A'}}
+// The compiler couldn't export A::bar() here since A::bar() is declared above without exported.
+// See [module.interface]/p6 for details.
+export void A::bar(); // expected-error {{cannot export 'bar' here because it had be declared in 'A'}}
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<
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D112903.384645.patch
Type: text/x-patch
Size: 3663 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211104/7e8bcdad/attachment-0001.bin>
More information about the cfe-commits
mailing list