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