diff options
author | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2022-01-14 10:21:42 +0800 |
---|---|---|
committer | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2022-01-14 10:21:42 +0800 |
commit | 4f8916cfdd941db2a4c4cdad6e5bc549532277a2 (patch) | |
tree | e7cdad52cc0f1cca332e1434ab8bbe76ced5ba3a /clang/lib/Sema/SemaModule.cpp | |
parent | b8367518e795741dde702bf7a8aa550fc8cd6f80 (diff) | |
download | llvm-4f8916cfdd941db2a4c4cdad6e5bc549532277a2.zip llvm-4f8916cfdd941db2a4c4cdad6e5bc549532277a2.tar.gz llvm-4f8916cfdd941db2a4c4cdad6e5bc549532277a2.tar.bz2 |
[C++20] [Modules] Exit early if export decl is not valid
This patch fixes a crash due to following simple program:
> export struct Unit {
> bool operator<(const Unit&);
> };
It would crash since the compiler would set the module ownership for
Unit. And the declaration with a module ownership is assumed to own a
module. But here isn't one. So here is the crash.
This patch fixes this by exiting early if it finds the export decl is
already invalid.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D117093
Diffstat (limited to 'clang/lib/Sema/SemaModule.cpp')
-rw-r--r-- | clang/lib/Sema/SemaModule.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index a4b9f3c..996063f 100644 --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -527,21 +527,30 @@ Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, // Set this temporarily so we know the export-declaration was braced. D->setRBraceLoc(LBraceLoc); + CurContext->addDecl(D); + PushDeclContext(S, D); + // C++2a [module.interface]p1: // An export-declaration shall appear only [...] in the purview of a module // interface unit. An export-declaration shall not appear directly or // indirectly within [...] a private-module-fragment. if (ModuleScopes.empty() || !ModuleScopes.back().Module->isModulePurview()) { Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0; + D->setInvalidDecl(); + return D; } else if (!ModuleScopes.back().ModuleInterface) { Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1; Diag(ModuleScopes.back().BeginLoc, diag::note_not_module_interface_add_export) << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export "); + D->setInvalidDecl(); + return D; } else if (ModuleScopes.back().Module->Kind == Module::PrivateModuleFragment) { Diag(ExportLoc, diag::err_export_in_private_module_fragment); Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment); + D->setInvalidDecl(); + return D; } for (const DeclContext *DC = CurContext; DC; DC = DC->getLexicalParent()) { @@ -553,7 +562,7 @@ Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, Diag(ND->getLocation(), diag::note_anonymous_namespace); // Don't diagnose internal-linkage declarations in this region. D->setInvalidDecl(); - break; + return D; } // A declaration is exported if it is [...] a namespace-definition @@ -572,10 +581,10 @@ Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, Diag(ExportLoc, diag::err_export_within_export); if (ED->hasBraces()) Diag(ED->getLocation(), diag::note_export); + D->setInvalidDecl(); + return D; } - CurContext->addDecl(D); - PushDeclContext(S, D); D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported); return D; } |