Author: Chuanqi Xu Date: 2025-03-05T19:05:49+08:00 New Revision: ea15e8b16eacdf2fb3a9715c5fc753b62fdfd516
URL: https://github.com/llvm/llvm-project/commit/ea15e8b16eacdf2fb3a9715c5fc753b62fdfd516 DIFF: https://github.com/llvm/llvm-project/commit/ea15e8b16eacdf2fb3a9715c5fc753b62fdfd516.diff LOG: [C++20] [Modules] Avoid use-but-not-defined error See the attached test for example. Added: clang/test/Modules/external-but-not-type-external.cppm Modified: clang/lib/Serialization/ASTWriterDecl.cpp Removed: ################################################################################ diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index a1810003f5425..88dd212259085 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -330,6 +330,12 @@ namespace clang { } bool clang::CanElideDeclDef(const Decl *D) { + bool isExternalWithNoLinkageType = false; + if (auto *VD = dyn_cast<ValueDecl>(D)) + if (VD->hasExternalFormalLinkage() && + !isExternalFormalLinkage(VD->getType()->getLinkage())) + isExternalWithNoLinkageType = true; + if (auto *FD = dyn_cast<FunctionDecl>(D)) { if (FD->isInlined() || FD->isConstexpr()) return false; @@ -339,6 +345,9 @@ bool clang::CanElideDeclDef(const Decl *D) { if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) return false; + + if (isExternalWithNoLinkageType && !FD->isExternC()) + return false; } if (auto *VD = dyn_cast<VarDecl>(D)) { @@ -352,6 +361,9 @@ bool clang::CanElideDeclDef(const Decl *D) { if (VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) return false; + + if (isExternalWithNoLinkageType && !VD->isExternC()) + return false; } return true; diff --git a/clang/test/Modules/external-but-not-type-external.cppm b/clang/test/Modules/external-but-not-type-external.cppm new file mode 100644 index 0000000000000..37a0d29104c5d --- /dev/null +++ b/clang/test/Modules/external-but-not-type-external.cppm @@ -0,0 +1,27 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: cd %t +// +// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-reduced-module-interface -o %t/a.pcm +// RUN: %clang_cc1 -std=c++20 %t/use.cc -fmodule-file=a=%t/a.pcm -fsyntax-only -verify + +//--- a.cppm +export module a; +namespace { +struct Local {}; +} + +export class A { +public: + void *external_but_not_type_external(Local *) { + return nullptr; + } +}; + +//--- use.cc +// expected-no-diagnostics +import a; +void *use() { + A a; + return a.external_but_not_type_external(nullptr); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits